Merge branch 'utf8'

This commit is contained in:
Vinzenz Schroeter 2025-01-16 21:33:01 +01:00
commit b6fa1b161e
52 changed files with 1927 additions and 789 deletions

View file

@ -17,6 +17,9 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: install lzma
run: sudo apt-get update && sudo apt-get install -y liblzma-dev
- name: build default features - name: build default features
run: cargo build --all --verbose run: cargo build --all --verbose
- name: build default features -- examples - name: build default features -- examples

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ out
.direnv .direnv
.envrc .envrc
result result
mutants.*

274
Cargo.lock generated
View file

@ -44,7 +44,7 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys",
] ]
[[package]] [[package]]
@ -54,14 +54,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"windows-sys 0.59.0", "windows-sys",
] ]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.93" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]] [[package]]
name = "askama" name = "askama"
@ -108,7 +108,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -186,9 +186,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.6.0" version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
@ -219,15 +219,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.8.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
[[package]] [[package]]
name = "bzip2" name = "bzip2"
version = "0.4.4" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" checksum = "bafdbf26611df8c14810e268ddceda071c297570a5fb360ceddf617fe417ef58"
dependencies = [ dependencies = [
"bzip2-sys", "bzip2-sys",
"libc", "libc",
@ -255,9 +255,9 @@ dependencies = [
[[package]] [[package]]
name = "cargo-platform" name = "cargo-platform"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -273,7 +273,7 @@ dependencies = [
"semver", "semver",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror 1.0.69",
] ]
[[package]] [[package]]
@ -282,24 +282,24 @@ version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb"
dependencies = [ dependencies = [
"clap 4.5.20", "clap 4.5.26",
"heck 0.4.1", "heck 0.4.1",
"indexmap 2.6.0", "indexmap 2.7.0",
"log", "log",
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"serde_json", "serde_json",
"syn 2.0.87", "syn 2.0.96",
"tempfile", "tempfile",
"toml 0.8.19", "toml 0.8.19",
] ]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.0" version = "1.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
@ -331,23 +331,23 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.20" version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive 4.5.18", "clap_derive 4.5.24",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.20" version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
"clap_lex 0.7.2", "clap_lex 0.7.4",
"strsim 0.11.1", "strsim 0.11.1",
] ]
@ -366,14 +366,14 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.18" version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -387,9 +387,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.2" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
@ -399,9 +399,9 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -449,12 +449,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.9" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys",
] ]
[[package]] [[package]]
@ -465,20 +465,20 @@ checksum = "311a6d2f1f9d60bff73d2c78a0af97ed27f79672f15c238192a5bbb64db56d00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.2.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.34" version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@ -528,9 +528,9 @@ dependencies = [
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]] [[package]]
name = "goblin" name = "goblin"
@ -551,9 +551,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.1" version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]] [[package]]
name = "heck" name = "heck"
@ -578,9 +578,9 @@ dependencies = [
[[package]] [[package]]
name = "http" name = "http"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@ -605,12 +605,12 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.6.0" version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.15.1", "hashbrown 0.15.2",
] ]
[[package]] [[package]]
@ -621,9 +621,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.11" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]] [[package]]
name = "jobserver" name = "jobserver"
@ -644,15 +644,15 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.162" version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.14" version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]] [[package]]
name = "log" name = "log"
@ -690,9 +690,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.0" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
dependencies = [ dependencies = [
"adler2", "adler2",
] ]
@ -778,18 +778,18 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.89" version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.37" version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -842,15 +842,15 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.40" version = "0.38.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.7.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.52.0", "windows-sys",
] ]
[[package]] [[package]]
@ -876,43 +876,43 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.23" version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.215" version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.215" version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.132" version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -931,24 +931,24 @@ dependencies = [
[[package]] [[package]]
name = "servicepoint" name = "servicepoint"
version = "0.12.0" version = "0.13.0"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"bzip2", "bzip2",
"clap 4.5.20", "clap 4.5.26",
"flate2", "flate2",
"log", "log",
"once_cell", "once_cell",
"rand", "rand",
"rust-lzma", "rust-lzma",
"thiserror", "thiserror 2.0.11",
"tungstenite", "tungstenite",
"zstd", "zstd",
] ]
[[package]] [[package]]
name = "servicepoint_binding_c" name = "servicepoint_binding_c"
version = "0.12.0" version = "0.13.0"
dependencies = [ dependencies = [
"cbindgen", "cbindgen",
"servicepoint", "servicepoint",
@ -956,10 +956,10 @@ dependencies = [
[[package]] [[package]]
name = "servicepoint_binding_uniffi" name = "servicepoint_binding_uniffi"
version = "0.12.0" version = "0.13.0"
dependencies = [ dependencies = [
"servicepoint", "servicepoint",
"thiserror", "thiserror 2.0.11",
"uniffi", "uniffi",
"uniffi-bindgen-cs", "uniffi-bindgen-cs",
"uniffi-bindgen-go", "uniffi-bindgen-go",
@ -1025,9 +1025,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.87" version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1042,15 +1042,16 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.14.0" version = "3.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"getrandom",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.59.0", "windows-sys",
] ]
[[package]] [[package]]
@ -1079,7 +1080,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
dependencies = [
"thiserror-impl 2.0.11",
] ]
[[package]] [[package]]
@ -1090,7 +1100,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
]
[[package]]
name = "thiserror-impl"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
] ]
[[package]] [[package]]
@ -1129,7 +1150,7 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [ dependencies = [
"indexmap 2.6.0", "indexmap 2.7.0",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -1138,9 +1159,9 @@ dependencies = [
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
version = "0.24.0" version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"bytes", "bytes",
@ -1150,7 +1171,7 @@ dependencies = [
"log", "log",
"rand", "rand",
"sha1", "sha1",
"thiserror", "thiserror 2.0.11",
"utf-8", "utf-8",
] ]
@ -1162,15 +1183,15 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.8.0" version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.13" version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]] [[package]]
name = "unicode-linebreak" name = "unicode-linebreak"
@ -1218,8 +1239,8 @@ dependencies = [
[[package]] [[package]]
name = "uniffi-bindgen-go" name = "uniffi-bindgen-go"
version = "0.2.1+v0.25.0" version = "0.2.2+v0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"askama 0.12.1", "askama 0.12.1",
@ -1234,15 +1255,15 @@ dependencies = [
"serde_json", "serde_json",
"textwrap", "textwrap",
"toml 0.5.11", "toml 0.5.11",
"uniffi_bindgen 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_bindgen 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
] ]
[[package]] [[package]]
name = "uniffi_bindgen" name = "uniffi_bindgen"
version = "0.25.0" version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"askama 0.12.1", "askama 0.12.1",
@ -1257,9 +1278,9 @@ dependencies = [
"serde", "serde",
"textwrap", "textwrap",
"toml 0.5.11", "toml 0.5.11",
"uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_udl 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
] ]
[[package]] [[package]]
@ -1322,10 +1343,10 @@ dependencies = [
[[package]] [[package]]
name = "uniffi_checksum_derive" name = "uniffi_checksum_derive"
version = "0.25.0" version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1334,7 +1355,7 @@ version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce" source = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?rev=f68639fbc720b50ebe561ba75c66c84dc456bdce#f68639fbc720b50ebe561ba75c66c84dc456bdce"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1344,7 +1365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]
@ -1376,7 +1397,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde", "serde",
"syn 2.0.87", "syn 2.0.96",
"toml 0.5.11", "toml 0.5.11",
"uniffi_build", "uniffi_build",
"uniffi_meta 0.25.3", "uniffi_meta 0.25.3",
@ -1385,12 +1406,12 @@ dependencies = [
[[package]] [[package]]
name = "uniffi_meta" name = "uniffi_meta"
version = "0.25.0" version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
"siphasher", "siphasher",
"uniffi_checksum_derive 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_checksum_derive 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
] ]
[[package]] [[package]]
@ -1419,7 +1440,7 @@ dependencies = [
[[package]] [[package]]
name = "uniffi_testing" name = "uniffi_testing"
version = "0.25.0" version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"camino", "camino",
@ -1456,12 +1477,12 @@ dependencies = [
[[package]] [[package]]
name = "uniffi_udl" name = "uniffi_udl"
version = "0.25.0" version = "0.25.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_meta 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "uniffi_testing 0.25.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
"weedle2 4.0.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240)", "weedle2 4.0.0 (git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c)",
] ]
[[package]] [[package]]
@ -1529,7 +1550,7 @@ dependencies = [
[[package]] [[package]]
name = "weedle2" name = "weedle2"
version = "4.0.0" version = "4.0.0"
source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=a77dc0462dc18d53846c758155ab4e0a42e5b240#a77dc0462dc18d53846c758155ab4e0a42e5b240" source = "git+https://github.com/NordSecurity/uniffi-bindgen-go.git?rev=ba23bab72f1a9bcc39ce81924d3d9265598e017c#ba23bab72f1a9bcc39ce81924d3d9265598e017c"
dependencies = [ dependencies = [
"nom", "nom",
] ]
@ -1564,7 +1585,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys",
] ]
[[package]] [[package]]
@ -1573,15 +1594,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"
@ -1657,9 +1669,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.20" version = "0.6.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -1691,7 +1703,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.87", "syn 2.0.96",
] ]
[[package]] [[package]]

View file

@ -8,10 +8,10 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.12.0" version = "0.13.0"
[workspace.lints.rust] [workspace.lints.rust]
missing-docs = "warn" missing-docs = "warn"
[workspace.dependencies] [workspace.dependencies]
thiserror = "1.0.69" thiserror = "2.0"

View file

@ -16,12 +16,12 @@ crate-type = ["rlib"]
log = "0.4" log = "0.4"
bitvec = "1.0" bitvec = "1.0"
flate2 = { version = "1.0", optional = true } flate2 = { version = "1.0", optional = true }
bzip2 = { version = "0.4", optional = true } bzip2 = { version = "0.5", optional = true }
zstd = { version = "0.13", optional = true } zstd = { version = "0.13", optional = true }
rust-lzma = { version = "0.6.0", optional = true } rust-lzma = { version = "0.6", optional = true }
rand = { version = "0.8", optional = true } rand = { version = "0.8", optional = true }
tungstenite = { version = "0.24.0", optional = true } tungstenite = { version = "0.26", optional = true }
once_cell = { version = "1.20.2", optional = true } once_cell = { version = "1.20", optional = true }
thiserror.workspace = true thiserror.workspace = true
[features] [features]
@ -56,4 +56,4 @@ clap = { version = "4.5", features = ["derive"] }
workspace = true workspace = true
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View file

@ -17,7 +17,7 @@ cargo add servicepoint
or or
```toml ```toml
[dependencies] [dependencies]
servicepoint = "0.12.0" servicepoint = "0.13.0"
``` ```
## Examples ## Examples
@ -39,8 +39,11 @@ Execute `cargo run --example` for a list of available examples and `cargo run --
## Note on stability ## Note on stability
This library is still in early development. This library can be used for creative project or just to play around with the display.
You can absolutely use it, and it works, but expect minor breaking changes with every version bump. A decent coverage by unit tests prevents major problems and I also test this with my own projects, which mostly use up-to-date versions.
That being said, the API is still being worked on.
Expect minor breaking changes with every version bump.
Please specify the full version including patch in your Cargo.toml until 1.0 is released. Please specify the full version including patch in your Cargo.toml until 1.0 is released.
## Features ## Features

View file

@ -1,8 +1,7 @@
//! An example for how to send text to the display. //! An example for how to send text to the display.
use clap::Parser; use clap::Parser;
use servicepoint::*;
use servicepoint::{CharGrid, Command, Connection, Cp437Grid, Origin};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {
@ -42,10 +41,8 @@ fn main() {
} }
let text = cli.text.join("\n"); let text = cli.text.join("\n");
let grid = CharGrid::from(text); let grid = CharGrid::wrap_str(TILE_WIDTH, &text);
let grid = Cp437Grid::from(grid);
connection connection
.send(Command::Cp437Data(Origin::ZERO, grid)) .send(Command::Utf8Data(Origin::ZERO, grid))
.expect("sending text failed"); .expect("sending text failed");
} }

View file

@ -1,7 +1,6 @@
//! Show a brightness level test pattern on screen //! Show a brightness level test pattern on screen
use clap::Parser; use clap::Parser;
use servicepoint::*; use servicepoint::*;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]

View file

@ -1,11 +1,9 @@
//! A simple game of life implementation to show how to render graphics to the display. //! A simple game of life implementation to show how to render graphics to the display.
use std::thread;
use clap::Parser; use clap::Parser;
use rand::{distributions, Rng}; use rand::{distributions, Rng};
use servicepoint::*; use servicepoint::*;
use std::thread;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {

View file

@ -1,10 +1,8 @@
//! A simple example for how to send pixel data to the display. //! A simple example for how to send pixel data to the display.
use std::thread;
use clap::Parser; use clap::Parser;
use servicepoint::*; use servicepoint::*;
use std::thread;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {

View file

@ -1,13 +1,10 @@
//! A simple example for how to set brightnesses for tiles on the screen. //! A simple example for how to set brightnesses for tiles on the screen.
//! Continuously changes the tiles in a random window to random brightnesses. //! Continuously changes the tiles in a random window to random brightnesses.
use std::time::Duration;
use clap::Parser; use clap::Parser;
use rand::Rng; use rand::Rng;
use servicepoint::Command::{BitmapLinearWin, Brightness, CharBrightness};
use servicepoint::*; use servicepoint::*;
use std::time::Duration;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {
@ -31,7 +28,7 @@ fn main() {
let mut filled_grid = Bitmap::max_sized(); let mut filled_grid = Bitmap::max_sized();
filled_grid.fill(true); filled_grid.fill(true);
let command = BitmapLinearWin( let command = Command::BitmapLinearWin(
Origin::ZERO, Origin::ZERO,
filled_grid, filled_grid,
CompressionCode::Lzma, CompressionCode::Lzma,
@ -41,7 +38,7 @@ fn main() {
// set all pixels to the same random brightness // set all pixels to the same random brightness
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
connection.send(Brightness(rng.gen())).unwrap(); connection.send(Command::Brightness(rng.gen())).unwrap();
// continuously update random windows to new random brightness // continuously update random windows to new random brightness
loop { loop {
@ -61,7 +58,9 @@ fn main() {
} }
} }
connection.send(CharBrightness(origin, luma)).unwrap(); connection
.send(Command::CharBrightness(origin, luma))
.unwrap();
std::thread::sleep(wait_duration); std::thread::sleep(wait_duration);
} }
} }

View file

@ -1,11 +1,9 @@
//! An example on how to modify the image on screen without knowing the current content. //! An example on how to modify the image on screen without knowing the current content.
use clap::Parser;
use servicepoint::*;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use clap::Parser;
use servicepoint::*;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {
#[arg(short, long, default_value = "localhost:2342")] #[arg(short, long, default_value = "localhost:2342")]
@ -34,7 +32,11 @@ fn main() {
} }
connection connection
.send(Command::BitmapLinearWin(Origin::ZERO, enabled_pixels.clone(), CompressionCode::Lzma)) .send(Command::BitmapLinearWin(
Origin::ZERO,
enabled_pixels.clone(),
CompressionCode::Lzma,
))
.expect("could not send command to display"); .expect("could not send command to display");
thread::sleep(sleep_duration); thread::sleep(sleep_duration);
} }

View file

@ -0,0 +1,10 @@
/// A byte-packed vector of booleans.
///
/// The implementation is provided by [bitvec].
/// This is an alias for the specific type of [bitvec::BitVec] used in this crate.
pub type BitVec = bitvec::BitVec<u8, bitvec::Msb0>;
pub mod bitvec {
//! Re-export of the used library [mod@bitvec].
pub use bitvec::prelude::*;
}

View file

@ -1,10 +1,23 @@
use bitvec::order::Msb0; use crate::data_ref::DataRef;
use bitvec::prelude::BitSlice; use crate::BitVec;
use bitvec::slice::IterMut; use crate::*;
use ::bitvec::order::Msb0;
use ::bitvec::prelude::BitSlice;
use ::bitvec::slice::IterMut;
use crate::{BitVec, DataRef, Grid, PIXEL_HEIGHT, PIXEL_WIDTH}; /// A fixed-size 2D grid of booleans.
///
/// A grid of pixels stored in packed bytes. /// The values are stored in packed bytes (8 values per byte) in the same order as used by the display for storing pixels.
/// This means that no conversion is necessary for sending the data to the display.
/// The downside is that the width has to be a multiple of 8.
///
/// # Examples
///
/// ```rust
/// use servicepoint::Bitmap;
/// let mut bitmap = Bitmap::new(8, 2);
///
/// ```
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Bitmap { pub struct Bitmap {
width: usize, width: usize,
@ -26,7 +39,11 @@ impl Bitmap {
/// ///
/// - when the width is not dividable by 8 /// - when the width is not dividable by 8
pub fn new(width: usize, height: usize) -> Self { pub fn new(width: usize, height: usize) -> Self {
assert_eq!(width % 8, 0); assert_eq!(
width % 8,
0,
"width must be a multiple of 8, but is {width}"
);
Self { Self {
width, width,
height, height,
@ -176,11 +193,38 @@ impl From<Bitmap> for Vec<u8> {
} }
impl From<Bitmap> for BitVec { impl From<Bitmap> for BitVec {
/// Turns a [Bitmap] into the underlying [BitVec].
fn from(value: Bitmap) -> Self { fn from(value: Bitmap) -> Self {
value.bit_vec value.bit_vec
} }
} }
impl From<&ValueGrid<bool>> for Bitmap {
/// Converts a grid of [bool]s into a [Bitmap].
///
/// # Panics
///
/// - when the width of `value` is not dividable by 8
fn from(value: &ValueGrid<bool>) -> Self {
let mut result = Self::new(value.width(), value.height());
for (mut to, from) in result.iter_mut().zip(value.iter()) {
*to = *from;
}
result
}
}
impl From<&Bitmap> for ValueGrid<bool> {
/// Converts a [Bitmap] into a grid of [bool]s.
fn from(value: &Bitmap) -> Self {
let mut result = Self::new(value.width(), value.height());
for (to, from) in result.iter_mut().zip(value.iter()) {
*to = *from;
}
result
}
}
pub struct IterRows<'t> { pub struct IterRows<'t> {
bitmap: &'t Bitmap, bitmap: &'t Bitmap,
row: usize, row: usize,
@ -203,7 +247,7 @@ impl<'t> Iterator for IterRows<'t> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{Bitmap, DataRef, Grid}; use crate::{BitVec, Bitmap, DataRef, Grid, ValueGrid};
#[test] #[test]
fn fill() { fn fill() {
@ -295,4 +339,24 @@ mod tests {
data[1] = 0x0F; data[1] = 0x0F;
assert!(grid.get(7, 1)); assert!(grid.get(7, 1));
} }
#[test]
fn to_bitvec() {
let mut grid = Bitmap::new(8, 2);
grid.set(0, 0, true);
let bitvec: BitVec = grid.into();
assert_eq!(bitvec.as_raw_slice(), [0x80, 0x00]);
}
#[test]
fn from_bool_grid() {
let original = ValueGrid::load(
8,
1,
&[true, false, true, false, true, false, true, false],
);
let converted = Bitmap::from(&original);
let reconverted = ValueGrid::from(&converted);
assert_eq!(original, reconverted);
}
} }

View file

@ -1,5 +1,3 @@
use crate::{Grid, PrimitiveGrid};
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
use rand::{ use rand::{
distributions::{Distribution, Standard}, distributions::{Distribution, Standard},
@ -22,28 +20,6 @@ use rand::{
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd)]
pub struct Brightness(u8); pub struct Brightness(u8);
/// A grid containing brightness values.
///
/// # Examples
///
/// ```rust
/// # use servicepoint::{Brightness, BrightnessGrid, Command, Connection, Grid, Origin};
/// let mut grid = BrightnessGrid::new(2,2);
/// grid.set(0, 0, Brightness::MIN);
/// grid.set(1, 1, Brightness::MIN);
///
/// # let connection = Connection::open("127.0.0.1:2342").unwrap();
/// connection.send(Command::CharBrightness(Origin::new(3, 7), grid)).unwrap()
/// ```
pub type BrightnessGrid = PrimitiveGrid<Brightness>;
impl BrightnessGrid {
/// Like [Self::load], but ignoring any out-of-range brightness values
pub fn saturating_load(width: usize, height: usize, data: &[u8]) -> Self {
PrimitiveGrid::load(width, height, data).map(Brightness::saturating_from)
}
}
impl From<Brightness> for u8 { impl From<Brightness> for u8 {
fn from(brightness: Brightness) -> Self { fn from(brightness: Brightness) -> Self {
Self::from(&brightness) Self::from(&brightness)
@ -92,41 +68,6 @@ impl Default for Brightness {
} }
} }
impl From<BrightnessGrid> for Vec<u8> {
fn from(value: PrimitiveGrid<Brightness>) -> Self {
value
.iter()
.map(|brightness| (*brightness).into())
.collect()
}
}
impl From<&BrightnessGrid> for PrimitiveGrid<u8> {
fn from(value: &PrimitiveGrid<Brightness>) -> Self {
let u8s = value
.iter()
.map(|brightness| (*brightness).into())
.collect::<Vec<u8>>();
PrimitiveGrid::load(value.width(), value.height(), &u8s)
}
}
impl TryFrom<PrimitiveGrid<u8>> for BrightnessGrid {
type Error = u8;
fn try_from(value: PrimitiveGrid<u8>) -> Result<Self, Self::Error> {
let brightnesses = value
.iter()
.map(|b| Brightness::try_from(*b))
.collect::<Result<Vec<_>, _>>()?;
Ok(BrightnessGrid::load(
value.width(),
value.height(),
&brightnesses,
))
}
}
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
impl Distribution<Brightness> for Standard { impl Distribution<Brightness> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Brightness { fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Brightness {
@ -137,7 +78,6 @@ impl Distribution<Brightness> for Standard {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::DataRef;
#[test] #[test]
fn brightness_from_u8() { fn brightness_from_u8() {
@ -154,24 +94,9 @@ mod tests {
} }
} }
#[test]
fn to_u8_grid() {
let mut grid = BrightnessGrid::new(2, 2);
grid.set(1, 0, Brightness::MIN);
grid.set(0, 1, Brightness::MAX);
let actual = PrimitiveGrid::from(&grid);
assert_eq!(actual.data_ref(), &[11, 0, 11, 11]);
}
#[test] #[test]
fn saturating_convert() { fn saturating_convert() {
assert_eq!(Brightness::MAX, Brightness::saturating_from(100)); assert_eq!(Brightness::MAX, Brightness::saturating_from(100));
assert_eq!(Brightness(5), Brightness::saturating_from(5)); assert_eq!(Brightness(5), Brightness::saturating_from(5));
} }
#[test]
fn saturating_load() {
assert_eq!(BrightnessGrid::load(2,2, &[Brightness::MAX, Brightness::MAX, Brightness::MIN, Brightness::MAX]),
BrightnessGrid::saturating_load(2,2, &[255u8, 23, 0, 42]));
}
} }

View file

@ -0,0 +1,93 @@
use crate::brightness::Brightness;
use crate::grid::Grid;
use crate::value_grid::ValueGrid;
use crate::ByteGrid;
/// A grid containing brightness values.
///
/// # Examples
///
/// ```rust
/// # use servicepoint::{Brightness, BrightnessGrid, Command, Connection, Grid, Origin};
/// let mut grid = BrightnessGrid::new(2,2);
/// grid.set(0, 0, Brightness::MIN);
/// grid.set(1, 1, Brightness::MIN);
///
/// # let connection = Connection::open("127.0.0.1:2342").unwrap();
/// connection.send(Command::CharBrightness(Origin::new(3, 7), grid)).unwrap()
/// ```
pub type BrightnessGrid = ValueGrid<Brightness>;
impl BrightnessGrid {
/// Like [Self::load], but ignoring any out-of-range brightness values
pub fn saturating_load(width: usize, height: usize, data: &[u8]) -> Self {
ValueGrid::load(width, height, data).map(Brightness::saturating_from)
}
}
impl From<BrightnessGrid> for Vec<u8> {
fn from(value: ValueGrid<Brightness>) -> Self {
value
.iter()
.map(|brightness| (*brightness).into())
.collect()
}
}
impl From<&BrightnessGrid> for ByteGrid {
fn from(value: &ValueGrid<Brightness>) -> Self {
let u8s = value
.iter()
.map(|brightness| (*brightness).into())
.collect::<Vec<u8>>();
ValueGrid::load(value.width(), value.height(), &u8s)
}
}
impl TryFrom<ByteGrid> for BrightnessGrid {
type Error = u8;
fn try_from(value: ByteGrid) -> Result<Self, Self::Error> {
let brightnesses = value
.iter()
.map(|b| Brightness::try_from(*b))
.collect::<Result<Vec<_>, _>>()?;
Ok(BrightnessGrid::load(
value.width(),
value.height(),
&brightnesses,
))
}
}
#[cfg(test)]
mod tests {
use crate::value_grid::ValueGrid;
use crate::{Brightness, BrightnessGrid, DataRef, Grid};
#[test]
fn to_u8_grid() {
let mut grid = BrightnessGrid::new(2, 2);
grid.set(1, 0, Brightness::MIN);
grid.set(0, 1, Brightness::MAX);
let actual = ValueGrid::from(&grid);
assert_eq!(actual.data_ref(), &[11, 0, 11, 11]);
}
#[test]
fn saturating_load() {
assert_eq!(
BrightnessGrid::load(
2,
2,
&[
Brightness::MAX,
Brightness::MAX,
Brightness::MIN,
Brightness::MAX
]
),
BrightnessGrid::saturating_load(2, 2, &[255u8, 23, 0, 42])
);
}
}

View file

@ -0,0 +1,4 @@
use crate::ValueGrid;
/// A 2d grid of bytes - see [ValueGrid].
pub type ByteGrid = ValueGrid<u8>;

View file

@ -1,13 +1,71 @@
use crate::primitive_grid::SeriesError; use crate::{Grid, SetValueSeriesError, TryLoadValueGridError, ValueGrid};
use crate::{Grid, PrimitiveGrid}; use std::string::FromUtf8Error;
/// A grid containing UTF-8 characters. /// A grid containing UTF-8 characters.
pub type CharGrid = PrimitiveGrid<char>; ///
/// To send a CharGrid to the display, use [Command::Utf8Data](crate::Command::Utf8Data).
///
/// Also see [ValueGrid] for the non-specialized operations and examples.
///
/// # Examples
///
/// ```rust
/// # use servicepoint::{CharGrid, Command, Connection, Origin};
/// let grid = CharGrid::from("You can\nload multiline\nstrings directly");
/// assert_eq!(grid.get_row_str(1), Some("load multiline\0\0".to_string()));
///
/// # let connection = Connection::Fake;
/// let command = Command::Utf8Data(Origin::ZERO, grid);
/// ```
pub type CharGrid = ValueGrid<char>;
impl CharGrid { impl CharGrid {
/// Loads a [CharGrid] with the specified width from the provided text, wrapping to as many rows as needed.
///
/// The passed rows are extended with '\0' if needed.
///
/// returns: [CharGrid] that contains a copy of the provided data.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let grid = CharGrid::wrap_str(2, "abc\ndef");
/// ```
pub fn wrap_str(width: usize, text: &str) -> Self {
let lines = text
.split('\n')
.flat_map(move |x| {
x.chars()
.collect::<Vec<char>>()
.chunks(width)
.map(|c| {
let mut s = String::from_iter(c);
s.push_str(&"\0".repeat(width - s.chars().count()));
s
})
.collect::<Vec<String>>()
})
.collect::<Vec<String>>();
let height = lines.len();
let mut result = Self::new(width, height);
for (row, text_line) in lines.iter().enumerate() {
result.set_row_str(row, text_line).unwrap()
}
result
}
/// Copies a column from the grid as a String. /// Copies a column from the grid as a String.
/// ///
/// Returns [None] if x is out of bounds. /// Returns [None] if x is out of bounds.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let grid = CharGrid::from("ab\ncd");
/// let col = grid.get_col_str(0).unwrap(); // "ac"
/// ```
pub fn get_col_str(&self, x: usize) -> Option<String> { pub fn get_col_str(&self, x: usize) -> Option<String> {
Some(String::from_iter(self.get_col(x)?)) Some(String::from_iter(self.get_col(x)?))
} }
@ -15,42 +73,91 @@ impl CharGrid {
/// Copies a row from the grid as a String. /// Copies a row from the grid as a String.
/// ///
/// Returns [None] if y is out of bounds. /// Returns [None] if y is out of bounds.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let grid = CharGrid::from("ab\ncd");
/// let row = grid.get_row_str(0).unwrap(); // "ab"
/// ```
pub fn get_row_str(&self, y: usize) -> Option<String> { pub fn get_row_str(&self, y: usize) -> Option<String> {
Some(String::from_iter(self.get_row(y)?)) Some(String::from_iter(self.get_row(y)?))
} }
/// Overwrites a row in the grid with a str. /// Overwrites a row in the grid with a str.
/// ///
/// Returns [SeriesError] if y is out of bounds or `row` is not of the correct size. /// Returns [SetValueSeriesError] if y is out of bounds or `row` is not of the correct size.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let mut grid = CharGrid::from("ab\ncd");
/// grid.set_row_str(0, "ef").unwrap();
/// ```
pub fn set_row_str( pub fn set_row_str(
&mut self, &mut self,
y: usize, y: usize,
value: &str, value: &str,
) -> Result<(), SeriesError> { ) -> Result<(), SetValueSeriesError> {
self.set_row(y, value.chars().collect::<Vec<_>>().as_ref()) self.set_row(y, value.chars().collect::<Vec<_>>().as_ref())
} }
/// Overwrites a column in the grid with a str. /// Overwrites a column in the grid with a str.
/// ///
/// Returns [SeriesError] if y is out of bounds or `row` is not of the correct size. /// Returns [SetValueSeriesError] if y is out of bounds or `row` is not of the correct size.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let mut grid = CharGrid::from("ab\ncd");
/// grid.set_col_str(0, "ef").unwrap();
/// ```
pub fn set_col_str( pub fn set_col_str(
&mut self, &mut self,
x: usize, x: usize,
value: &str, value: &str,
) -> Result<(), SeriesError> { ) -> Result<(), SetValueSeriesError> {
self.set_col(x, value.chars().collect::<Vec<_>>().as_ref()) self.set_col(x, value.chars().collect::<Vec<_>>().as_ref())
} }
/// Loads a [CharGrid] with the specified dimensions from the provided UTF-8 bytes.
///
/// returns: [CharGrid] that contains the provided data, or [FromUtf8Error] if the data is invalid.
///
/// # Examples
///
/// ```
/// # use servicepoint::CharGrid;
/// let grid = CharGrid::load_utf8(2, 2, [97u8, 98, 99, 100].to_vec());
/// ```
pub fn load_utf8(
width: usize,
height: usize,
bytes: Vec<u8>,
) -> Result<CharGrid, LoadUtf8Error> {
let s: Vec<char> = String::from_utf8(bytes)?.chars().collect();
Ok(CharGrid::try_load(width, height, s)?)
}
}
#[derive(Debug, thiserror::Error)]
pub enum LoadUtf8Error {
#[error(transparent)]
FromUtf8Error(#[from] FromUtf8Error),
#[error(transparent)]
TryLoadError(#[from] TryLoadValueGridError),
} }
impl From<&str> for CharGrid { impl From<&str> for CharGrid {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
let value = value.replace("\r\n", "\n"); let value = value.replace("\r\n", "\n");
let mut lines = value let mut lines = value.split('\n').collect::<Vec<_>>();
.split('\n') let width = lines
.map(move |line| line.trim_end()) .iter()
.collect::<Vec<_>>(); .fold(0, move |a, x| std::cmp::max(a, x.chars().count()));
let width =
lines.iter().fold(0, move |a, x| std::cmp::max(a, x.len()));
while lines.last().is_some_and(move |line| line.is_empty()) { while lines.last().is_some_and(move |line| line.is_empty()) {
_ = lines.pop(); _ = lines.pop();
@ -73,26 +180,63 @@ impl From<String> for CharGrid {
} }
} }
impl From<CharGrid> for String {
fn from(grid: CharGrid) -> Self {
String::from(&grid)
}
}
impl From<&CharGrid> for String { impl From<&CharGrid> for String {
/// Converts a [CharGrid] into a [String].
///
/// Rows are separated by '\n'.
///
/// # Examples
///
/// ```rust
/// # use servicepoint::CharGrid;
/// let grid = CharGrid::from("ab\ncd");
/// let string = String::from(grid);
/// let grid = CharGrid::from(string);
/// ```
fn from(value: &CharGrid) -> Self { fn from(value: &CharGrid) -> Self {
value value
.iter_rows() .iter_rows()
.map(move |chars| { .map(String::from_iter)
chars .collect::<Vec<String>>()
.collect::<String>()
.replace('\0', " ")
.trim_end()
.to_string()
})
.collect::<Vec<_>>()
.join("\n") .join("\n")
} }
} }
impl From<&CharGrid> for Vec<u8> {
/// Converts a [CharGrid] into a [`Vec<u8>`].
///
/// Rows are not separated.
///
/// # Examples
///
/// ```rust
/// # use servicepoint::{CharGrid, Grid};
/// let grid = CharGrid::from("ab\ncd");
/// let height = grid.height();
/// let width = grid.width();
/// let grid = CharGrid::load_utf8(width, height, grid.into());
/// ```
fn from(value: &CharGrid) -> Self {
String::from_iter(value.iter()).into_bytes()
}
}
impl From<CharGrid> for Vec<u8> {
/// See [`From<&CharGrid>::from`].
fn from(value: CharGrid) -> Self {
Self::from(&value)
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::Grid;
#[test] #[test]
fn col_str() { fn col_str() {
let mut grid = CharGrid::new(2, 3); let mut grid = CharGrid::new(2, 3);
@ -109,7 +253,7 @@ mod test {
assert_eq!(grid.get_row_str(1), Some(String::from("\0\0"))); assert_eq!(grid.get_row_str(1), Some(String::from("\0\0")));
assert_eq!( assert_eq!(
grid.set_row_str(1, "abc"), grid.set_row_str(1, "abc"),
Err(SeriesError::InvalidLength { Err(SetValueSeriesError::InvalidLength {
expected: 2, expected: 2,
actual: 3 actual: 3
}) })
@ -120,10 +264,35 @@ mod test {
#[test] #[test]
fn str_to_char_grid() { fn str_to_char_grid() {
let original = "Hello\r\nWorld!\n...\n"; // conversion with .to_string() covers one more line
let original = "Hello\r\nWorld!\n...\n".to_string();
let grid = CharGrid::from(original); let grid = CharGrid::from(original);
assert_eq!(3, grid.height()); assert_eq!(3, grid.height());
let actual = String::from(&grid); assert_eq!("Hello\0\nWorld!\n...\0\0\0", String::from(grid));
assert_eq!("Hello\nWorld!\n...", actual); }
#[test]
fn round_trip_bytes() {
let grid = CharGrid::from("Hello\0\nWorld!\n...\0\0\0");
let bytes: Vec<u8> = grid.clone().into();
let copy =
CharGrid::load_utf8(grid.width(), grid.height(), bytes).unwrap();
assert_eq!(grid, copy);
}
#[test]
fn round_trip_string() {
let grid = CharGrid::from("Hello\0\nWorld!\n...\0\0\0");
let str: String = grid.clone().into();
let copy = CharGrid::from(str);
assert_eq!(grid, copy);
}
#[test]
fn wrap_str() {
let grid = CharGrid::wrap_str(2, "abc\ndef");
assert_eq!(4, grid.height());
assert_eq!("ab\nc\0\nde\nf\0", String::from(grid));
} }
} }

View file

@ -1,10 +1,7 @@
use crate::{ use crate::command_code::CommandCode;
command_code::CommandCode, use crate::compression::into_decompressed;
compression::into_decompressed, use crate::value_grid::ValueGrid;
packet::{Header, Packet}, use crate::*;
Bitmap, Brightness, BrightnessGrid, CompressionCode, Cp437Grid, Origin,
Pixels, PrimitiveGrid, BitVec, Tiles, TILE_SIZE,
};
/// Type alias for documenting the meaning of the u16 in enum values /// Type alias for documenting the meaning of the u16 in enum values
pub type Offset = usize; pub type Offset = usize;
@ -41,7 +38,7 @@ pub type Offset = usize;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{Brightness, Command, Connection, packet::Packet}; /// use servicepoint::{Brightness, Command, Connection, Packet};
/// # /// #
/// // create command /// // create command
/// let command = Command::Brightness(Brightness::MAX); /// let command = Command::Brightness(Brightness::MAX);
@ -74,14 +71,29 @@ pub enum Command {
/// Show text on the screen. /// Show text on the screen.
/// ///
/// The text is sent in the form of a 2D grid of [CP-437] encoded characters. /// The text is sent in the form of a 2D grid of UTF-8 encoded characters (the default encoding in rust).
/// ///
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use servicepoint::{Command, Connection, Origin}; /// # use servicepoint::{Command, Connection, Origin, CharGrid};
/// # let connection = Connection::Fake;
/// let grid = CharGrid::from("Hello,\nWorld!");
/// connection.send(Command::Utf8Data(Origin::ZERO, grid)).expect("send failed");
/// ```
Utf8Data(Origin<Tiles>, CharGrid),
/// Show text on the screen.
///
/// The text is sent in the form of a 2D grid of [CP-437] encoded characters.
///
/// <div class="warning">You probably want to use [Command::Utf8Data] instead</div>
///
/// # Examples
///
/// ```rust
/// # use servicepoint::{Command, Connection, Origin, CharGrid, Cp437Grid};
/// # let connection = Connection::Fake; /// # let connection = Connection::Fake;
/// use servicepoint::{CharGrid, Cp437Grid};
/// let grid = CharGrid::from("Hello,\nWorld!"); /// let grid = CharGrid::from("Hello,\nWorld!");
/// let grid = Cp437Grid::from(&grid); /// let grid = Cp437Grid::from(&grid);
/// connection.send(Command::Cp437Data(Origin::ZERO, grid)).expect("send failed"); /// connection.send(Command::Cp437Data(Origin::ZERO, grid)).expect("send failed");
@ -234,6 +246,8 @@ pub enum TryFromPacketError {
/// The given brightness value is out of bounds /// The given brightness value is out of bounds
#[error("The given brightness value {0} is out of bounds.")] #[error("The given brightness value {0} is out of bounds.")]
InvalidBrightness(u8), InvalidBrightness(u8),
#[error(transparent)]
InvalidUtf8(#[from] std::string::FromUtf8Error),
} }
impl TryFrom<Packet> for Command { impl TryFrom<Packet> for Command {
@ -269,6 +283,7 @@ impl TryFrom<Packet> for Command {
CommandCode::CharBrightness => { CommandCode::CharBrightness => {
Self::packet_into_char_brightness(&packet) Self::packet_into_char_brightness(&packet)
} }
CommandCode::Utf8Data => Self::packet_into_utf8(&packet),
#[allow(deprecated)] #[allow(deprecated)]
CommandCode::BitmapLegacy => Ok(Command::BitmapLegacy), CommandCode::BitmapLegacy => Ok(Command::BitmapLegacy),
CommandCode::BitmapLinear => { CommandCode::BitmapLinear => {
@ -426,8 +441,7 @@ impl Command {
payload, payload,
} = packet; } = packet;
let grid = let grid = ValueGrid::load(*width as usize, *height as usize, payload);
PrimitiveGrid::load(*width as usize, *height as usize, payload);
let grid = match BrightnessGrid::try_from(grid) { let grid = match BrightnessGrid::try_from(grid) {
Ok(grid) => grid, Ok(grid) => grid,
Err(val) => return Err(TryFromPacketError::InvalidBrightness(val)), Err(val) => return Err(TryFromPacketError::InvalidBrightness(val)),
@ -489,18 +503,37 @@ impl Command {
Cp437Grid::load(*c as usize, *d as usize, payload), Cp437Grid::load(*c as usize, *d as usize, payload),
)) ))
} }
fn packet_into_utf8(
packet: &Packet,
) -> Result<Command, TryFromPacketError> {
let Packet {
header:
Header {
command_code: _,
a,
b,
c,
d,
},
payload,
} = packet;
let payload: Vec<_> =
String::from_utf8(payload.clone())?.chars().collect();
Ok(Command::Utf8Data(
Origin::new(*a as usize, *b as usize),
CharGrid::load(*c as usize, *d as usize, &payload),
))
}
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::command::TryFromPacketError;
use crate::command_code::CommandCode;
use crate::{ use crate::{
bitvec::prelude::BitVec, BitVec, Bitmap, Brightness, BrightnessGrid, CharGrid, Command,
command::TryFromPacketError, CompressionCode, Cp437Grid, Header, Origin, Packet, Pixels,
command_code::CommandCode,
origin::Pixels,
packet::{Header, Packet},
Bitmap, Brightness, BrightnessGrid, Command, CompressionCode, Origin,
PrimitiveGrid,
}; };
fn round_trip(original: Command) { fn round_trip(original: Command) {
@ -556,16 +589,18 @@ mod tests {
fn round_trip_char_brightness() { fn round_trip_char_brightness() {
round_trip(Command::CharBrightness( round_trip(Command::CharBrightness(
Origin::new(5, 2), Origin::new(5, 2),
PrimitiveGrid::new(7, 5), BrightnessGrid::new(7, 5),
)); ));
} }
#[test] #[test]
fn round_trip_cp437_data() { fn round_trip_cp437_data() {
round_trip(Command::Cp437Data( round_trip(Command::Cp437Data(Origin::new(5, 2), Cp437Grid::new(7, 5)));
Origin::new(5, 2), }
PrimitiveGrid::new(7, 5),
)); #[test]
fn round_trip_utf8_data() {
round_trip(Command::Utf8Data(Origin::new(5, 2), CharGrid::new(7, 5)));
} }
#[test] #[test]

View file

@ -21,6 +21,7 @@ pub(crate) enum CommandCode {
BitmapLinearWinBzip2 = 0x0018, BitmapLinearWinBzip2 = 0x0018,
#[cfg(feature = "compression_lzma")] #[cfg(feature = "compression_lzma")]
BitmapLinearWinLzma = 0x0019, BitmapLinearWinLzma = 0x0019,
Utf8Data = 0x0020,
#[cfg(feature = "compression_zstd")] #[cfg(feature = "compression_zstd")]
BitmapLinearWinZstd = 0x001A, BitmapLinearWinZstd = 0x001A,
} }
@ -93,6 +94,9 @@ impl TryFrom<u16> for CommandCode {
value if value == CommandCode::BitmapLinearWinBzip2 as u16 => { value if value == CommandCode::BitmapLinearWinBzip2 as u16 => {
Ok(CommandCode::BitmapLinearWinBzip2) Ok(CommandCode::BitmapLinearWinBzip2)
} }
value if value == CommandCode::Utf8Data as u16 => {
Ok(CommandCode::Utf8Data)
}
_ => Err(()), _ => Err(()),
} }
} }

Some files were not shown because too many files have changed in this diff Show more