Compare commits

..

10 Commits

Author SHA1 Message Date
tmerritt bdeefdb3b6 more formatting 2026-05-03 08:50:55 -04:00
tmerritt e3b8939082 config.toml: remove excluded files for coverage report
data_to_text.rs: change from . as unrecognized character to ' '
demo.rs: improves POC display of headers
tests/primitive_formatting.rs: initial tests of bool formatting
2026-04-14 07:43:20 -04:00
tmerritt 9852ef687d April bump 2026-04-04 13:14:43 -04:00
tmerritt e7e20f1d36 applies rustfmt to cleanup
uses std::env::current_dir to find out where the tests are running from
2025-08-14 07:48:23 -04:00
tmerritt 6d51a4d3a6 Duration to String enhanced with tests
Adds checks for if a bit in a u8 is set or clear
2025-07-23 11:19:22 -04:00
tmerritt 3280123d22 Adds Duration to String for converting a duration to a human readable length of time 2025-07-23 08:54:29 -04:00
tmerritt 0b11b91fe4 update tests 2025-06-12 14:33:43 -04:00
tmerritt 703ae38814 data_to_text basic testing 2025-06-06 09:14:32 -04:00
tmerritt f93131622f Start of data_to_text family 2025-06-05 14:19:45 -04:00
tmerritt 37cc9e4fdb 100% coverage 2025-06-02 16:02:54 -04:00
27 changed files with 970 additions and 564 deletions
+1 -2
View File
@@ -1,3 +1,2 @@
[alias] [alias]
coverage = "tarpaulin --out Html --skip-clean --output-dir coverage" coverage = "tarpaulin --out Html --skip-clean --output-dir coverage --exclude-files src/bin/* --exclude-files tests/*"
Generated
+45 -366
View File
@@ -4,154 +4,36 @@ version = 4
[[package]] [[package]]
name = "adler2" name = "adler2"
version = "2.0.0" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.1" version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "1.0.0" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "clap"
version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.4.2" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "env_logger"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
dependencies = [
"humantime",
"is-terminal",
"log",
"regex",
"termcolor",
]
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.12" version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys", "windows-sys",
@@ -165,9 +47,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.1.1" version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
@@ -175,82 +57,36 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.3.3" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"r-efi", "r-efi",
"wasi", "wasip2",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
[[package]]
name = "humantime"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f"
[[package]]
name = "is-terminal"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi",
"libc",
"windows-sys",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.172" version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.9.4" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.8" version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [ dependencies = [
"adler2", "adler2",
"simd-adler32",
] ]
[[package]] [[package]]
@@ -259,70 +95,17 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "r-efi" name = "r-efi"
version = "5.2.0" version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.0.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 = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
@@ -332,27 +115,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "strsim" name = "simd-adler32"
version = "0.11.1" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.20.0" version = "3.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom", "getrandom",
@@ -361,133 +133,40 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "trevors_utilities" name = "trevors_utilities"
version = "0.1.0" version = "0.1.0-20250606"
dependencies = [ dependencies = [
"clap",
"env_logger",
"flate2", "flate2",
"tempfile", "tempfile",
] ]
[[package]] [[package]]
name = "unicode-ident" name = "wasip2"
version = "1.0.18" version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [ dependencies = [
"wit-bindgen-rt", "wit-bindgen",
] ]
[[package]] [[package]]
name = "winapi-util" name = "windows-link"
version = "0.1.9" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
dependencies = [
"windows-sys",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [ dependencies = [
"windows-targets", "windows-link",
] ]
[[package]] [[package]]
name = "windows-targets" name = "wit-bindgen"
version = "0.52.6" version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
+2 -4
View File
@@ -1,10 +1,8 @@
[package] [package]
name = "trevors_utilities" name = "trevors_utilities"
version = "0.1.0" version = "0.1.0-20250606"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
flate2 = "1.0" flate2 = "1.0"
clap = { version = "4.5", features = ["derive"] } tempfile = "3"
env_logger = "0.10"
tempfile = "3.20"
+26
View File
@@ -0,0 +1,26 @@
# Trevors Utilities
## Overview
Trevors Utilities is a collection of code that Trevor has found useful.
All code has the following criteria:
- Traits as appropriate, implemented for concrete types
- All code must have 100% code coverage to be part of a 'tagged release'
- All code must have 100% documentation coverage with examples of inputs and outputs
## Code Areas
### Number System Conversion
A variety of methods for converting numbers between systems. Functionality includes
- Joining u8 values into u16 values with low and high bytes
- Splitting u16 values into the high and low u8 values
- Swapping endianness of u16 values
- Converting an array of bool values into the equivalent value in u8 with bits in MSB order
### Test Compression
Methods for compressing and decompressing test results using deflate compression.
+1
View File
@@ -0,0 +1 @@
q
+1
View File
@@ -0,0 +1 @@
0x71 q
+1
View File
@@ -0,0 +1 @@
the quick brown fox jumped over the lazy dog
@@ -0,0 +1,3 @@
0x74 0x68 0x65 0x20 0x71 0x75 0x69 0x63 0x6b 0x20 0x62 0x72 0x6f 0x77 0x6e 0x20 the quick brown
0x66 0x6f 0x78 0x20 0x6a 0x75 0x6d 0x70 0x65 0x64 0x20 0x6f 0x76 0x65 0x72 0x20 fox jumped over
0x74 0x68 0x65 0x20 0x6c 0x61 0x7a 0x79 0x20 0x64 0x6f 0x67 the lazy dog
+54
View File
@@ -0,0 +1,54 @@
use std::time::Duration;
use trevors_utilities::data_to_text::DataToText;
use trevors_utilities::duration_to_string::duration_to_string::{duration_to_string, SECONDS_IN_DAY, SECONDS_IN_HOUR, SECONDS_IN_MINUTE};
use trevors_utilities::format_with_commas::format_with_commas;
fn demo_header(title: &str, width: Option<u8>) {
let width = width.unwrap_or(80) as usize;
let num_leading = (width - title.len() - 4) / 2;
println!("{}{}", "-".repeat(width), "");
println!("|{}{} {}|", " ".repeat(num_leading), title, " ".repeat(num_leading));
println!("{}{}", "-".repeat(width), "");
}
fn duration_to_string_demo() {
demo_header("Duration to String", None);
println!();
let options = vec![
// 4 days, 3 hours, 19 minutes, 31 seconds
(4 * SECONDS_IN_DAY) + (3 * SECONDS_IN_HOUR) + (19 * SECONDS_IN_MINUTE) + (31),
// 0 days, 0 hours, 1 minute, 0 seconds
(0 * SECONDS_IN_DAY) + (0 * SECONDS_IN_HOUR) + (1 * SECONDS_IN_MINUTE) + 0,
// 0 days, 0 hours, 0 minutes, 1 second,
1,
];
for option in options {
println!("{}s becomes {}", format_with_commas(option), duration_to_string(Duration::from_secs(option as u64), Some(false)));
println!("{}s becomes {}", format_with_commas(option), duration_to_string(Duration::from_secs(option as u64), Some(true)));
println!("{}s becomes {}", format_with_commas(option), duration_to_string(Duration::from_secs(option as u64), None));
println!("--");
}
}
fn data_to_text_demo() {
demo_header("Data To Text", None);
let options: Vec<Vec<u8>> = vec![
(0..=255).collect(),
(0..128).collect(),
(0x20..=0x7f).collect()
];
for option in options { let data = DataToText::data_to_text(option.as_slice());
println!("{}", data);
}
}
fn main() {
println!("Demos for Trevors Utilities");
println!();
println!();
duration_to_string_demo();
data_to_text_demo();
}
+10
View File
@@ -0,0 +1,10 @@
use trevors_utilities::data_to_text::DataToText;
fn main() {
let text = "q";
let displayed_hex = DataToText::data_to_text(text.as_bytes());
println!("RAW: [{text}]");
println!("FORMATTED:\n{displayed_hex}");
}
+52
View File
@@ -0,0 +1,52 @@
pub struct DataToText {}
impl DataToText {
/// data_to_text_window
///
/// Convert a block of u8 data to text for user display skipping specified bytes
pub fn data_to_text_window(to_convert: &[u8], offset: usize, length: usize) -> String {
let convert_len = to_convert.len();
if offset >= convert_len {
return String::from("");
}
let end_of_window = offset.saturating_add(length).min(convert_len);
DataToText::data_to_text(&to_convert[offset..end_of_window])
}
/// data_to_text
///
/// Convert a block of u8 data to text for user display
pub fn data_to_text(to_convert: &[u8]) -> String {
let mut result = String::new();
let mut hex_line = String::new();
let mut ascii_line = String::new();
for (idx, byte) in to_convert.iter().enumerate() {
hex_line += &format!("0x{:02x} ", byte);
let ascii_char = if byte.is_ascii_graphic() {
*byte as char
} else {
' '
};
ascii_line.push(ascii_char);
if idx % 16 == 15 {
// Write full line
result += &format!("{:<96} {}\n", hex_line, ascii_line);
hex_line.clear();
ascii_line.clear();
}
}
// Final line if there are leftover bytes
if !hex_line.is_empty() {
result += &format!("{:<96} {}\n", hex_line, ascii_line);
}
result
}
}
@@ -0,0 +1,38 @@
use std::time::Duration;
pub const SECONDS_IN_MINUTE: u32 = 60;
pub const SECONDS_IN_HOUR: u32 = SECONDS_IN_MINUTE * 60;
pub const SECONDS_IN_DAY: u32 = SECONDS_IN_HOUR * 24;
pub fn duration_to_string(to_convert: Duration, show_zeros: Option<bool>) -> String {
const SECONDS_IN_DAY: u32 = 86400;
const SECONDS_IN_HOUR: u32 = 3600;
const SECONDS_IN_MINUTE: u32 = 60;
let should_show_zero = show_zeros.unwrap_or(false);
let mut total_seconds = to_convert.as_secs() as u32;
let mut parts = Vec::new();
let units = [
(SECONDS_IN_DAY, "day"),
(SECONDS_IN_HOUR, "hour"),
(SECONDS_IN_MINUTE, "minute"),
(1, "second"),
];
for &(unit_seconds, unit_name) in &units {
let count = total_seconds / unit_seconds;
total_seconds %= unit_seconds;
if count > 0 || should_show_zero {
let label = if count == 1 {
unit_name.to_string()
} else {
format!("{}s", unit_name)
};
parts.push(format!("{} {}", count, label));
}
}
parts.join(" ")
}
+2
View File
@@ -0,0 +1,2 @@
pub mod duration_to_string;
mod tests;
+110
View File
@@ -0,0 +1,110 @@
#[cfg(test)]
mod test {
use super::*;
use crate::duration_to_string::duration_to_string::duration_to_string;
use crate::duration_to_string::duration_to_string::*;
use std::time::Duration;
#[test]
fn multi_duration_to_string() {
let params: Vec<(&str, Duration, Option<bool>)> = vec![
("1 second", Duration::from_secs(1), Some(false)),
("4 seconds", Duration::from_secs(4), Some(false)),
("1 minute", Duration::from_secs(SECONDS_IN_MINUTE as u64),Some(false)),
("4 minutes", Duration::from_secs((SECONDS_IN_MINUTE * 4) as u64), Some(false)),
(
"1 hour",
Duration::from_secs(SECONDS_IN_HOUR as u64),
Some(false),
),
(
"4 hours",
Duration::from_secs((SECONDS_IN_HOUR * 4) as u64),
Some(false),
),
(
"4 hours 5 minutes",
Duration::from_secs((SECONDS_IN_HOUR * 4 + SECONDS_IN_MINUTE * 5) as u64),
Some(false),
),
(
"1 day",
Duration::from_secs(SECONDS_IN_DAY as u64),
Some(false),
),
(
"0 days 0 hours 0 minutes 1 second",
Duration::from_secs(1),
Some(true),
),
(
"0 days 0 hours 0 minutes 4 seconds",
Duration::from_secs(4),
Some(true),
),
(
"0 days 0 hours 1 minute 0 seconds",
Duration::from_secs(SECONDS_IN_MINUTE as u64),
Some(true),
),
(
"0 days 0 hours 4 minutes 0 seconds",
Duration::from_secs((SECONDS_IN_MINUTE * 4) as u64),
Some(true),
),
(
"0 days 1 hour 0 minutes 0 seconds",
Duration::from_secs(SECONDS_IN_HOUR as u64),
Some(true),
),
(
"0 days 4 hours 0 minutes 0 seconds",
Duration::from_secs((SECONDS_IN_HOUR * 4) as u64),
Some(true),
),
(
"0 days 4 hours 5 minutes 0 seconds",
Duration::from_secs((SECONDS_IN_HOUR * 4 + SECONDS_IN_MINUTE * 5) as u64),
Some(true),
),
(
"1 day 0 hours 0 minutes 0 seconds",
Duration::from_secs(SECONDS_IN_DAY as u64),
Some(true),
),
(
"1 day 0 hours 0 minutes 1 second",
Duration::from_secs((SECONDS_IN_DAY + 1) as u64),
Some(true),
),
("1 second", Duration::from_secs(1), None),
("4 seconds", Duration::from_secs(4), None),
(
"1 minute",
Duration::from_secs(SECONDS_IN_MINUTE as u64),
None,
),
(
"4 minutes",
Duration::from_secs((SECONDS_IN_MINUTE * 4) as u64),
None,
),
("1 hour", Duration::from_secs(SECONDS_IN_HOUR as u64), None),
(
"4 hours",
Duration::from_secs((SECONDS_IN_HOUR * 4) as u64),
None,
),
(
"4 hours 5 minutes",
Duration::from_secs((SECONDS_IN_HOUR * 4 + SECONDS_IN_MINUTE * 5) as u64),
None,
),
("1 day", Duration::from_secs(SECONDS_IN_DAY as u64), None),
];
for (expected, actual, show) in params {
assert_eq!(expected, duration_to_string(actual, show));
}
}
}
+11
View File
@@ -0,0 +1,11 @@
pub fn format_with_commas(mut num: u32) -> String {
let mut parts = Vec::new();
while num >= 1000 {
parts.push(format!("{:03}", num % 1000));
num /= 1000;
}
parts.push(num.to_string());
parts.reverse();
parts.join(",")
}
+5 -1
View File
@@ -1,2 +1,6 @@
pub mod test_compression; pub mod data_to_text;
pub mod duration_to_string;
pub mod number_system_conversion; pub mod number_system_conversion;
pub mod test_compression;
pub mod format_with_commas;
pub mod primitive_formatting;
+38 -6
View File
@@ -8,12 +8,12 @@ impl NumberSystemConversion {
/// ex: 0xff -> true, true, true, true, true, true, true, true /// ex: 0xff -> true, true, true, true, true, true, true, true
/// 0xa0 -> true, false, true, false, false, false, false, false /// 0xa0 -> true, false, true, false, false, false, false, false
pub fn byte_to_bool(from: u8) -> [bool; 8] { pub fn byte_to_bool(from: u8) -> [bool; 8] {
let mut return_values = [false; 8]; let mut result = [false; 8];
for i in 0..8 { for i in 0..8 {
let new_value = from >> i & 0x1 == 1; // Extract the i-th bit and convert it to a boolean
return_values[i as usize] = new_value; result[i] = ((from >> i) & 1) != 0;
} }
return_values result
} }
/// bool_to_byte /// bool_to_byte
@@ -94,7 +94,39 @@ impl NumberSystemConversion {
(high as u16) << 8 | low as u16 (high as u16) << 8 | low as u16
} }
pub fn join_bytes_u16_from_u8(high: u8, low: u8) -> u16 { /// clear_high_bits
low as u16 | ((high as u16) << 8) ///
/// Clear the 8 MSB of the value
///
/// ex: 0xffff -> 0x00ff
/// 0xabcd -> 0x00cd
pub fn clear_high_bits(to_clear: u16) -> u16 {
to_clear & 0x00ff
}
/// clear_low_bits
///
/// Clear the 8 LSB of the value
///
/// ex: 0xffff -> 0xff00
/// 0xabcd -> 0xab00
pub fn clear_low_bits(to_clear: u16) -> u16 {
to_clear & 0xff00
}
/// is_bit_set
///
/// Checks if a specified bit is set
pub fn is_bit_set(to_check: u8, bit_to_check: u8) -> bool {
(to_check >> bit_to_check) & 0x01 == 1
}
/// is_bit_clear
///
/// Checks if a specified bit is clear
/// LSB = 0 MSB = 7
pub fn is_bit_clear(to_check: u8, bit_to_check: u8) -> bool {
(to_check >> bit_to_check) & 0x01 != 1
} }
} }
+11
View File
@@ -0,0 +1,11 @@
pub fn bool_to_string(b: bool) -> String {
if b {
"1".to_string()
} else {
"0".to_string()
}
}
pub fn bool_array_to_string(b: &[bool]) -> String {
b.iter().map(|b| bool_to_string(*b)).collect::<Vec<String>>().join("")
}
+75 -86
View File
@@ -1,10 +1,11 @@
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::path::Path;
use flate2::Compression; use flate2::Compression;
use flate2::read::DeflateDecoder; use flate2::read::DeflateDecoder;
use flate2::write::DeflateEncoder; use flate2::write::DeflateEncoder;
use tempfile::tempfile; use std::fs::{File, OpenOptions};
use std::io;
use std::io::{Read, Write};
use std::path::Path;
use std::string::String;
pub struct TestCompression {} pub struct TestCompression {}
@@ -17,20 +18,24 @@ impl TestCompression {
encoder.finish().expect("Failed to finish compression") encoder.finish().expect("Failed to finish compression")
} }
pub fn decompress_to_string(compressed_data: &[u8]) -> Result<String, std::io::Error> { pub fn decompress_to_string(compressed_data: &[u8]) -> String {
let mut decoder = DeflateDecoder::new(compressed_data); let mut decoder = DeflateDecoder::new(compressed_data);
let mut decompressed = String::new(); let mut decompressed = String::new();
decoder.read_to_string(&mut decompressed)?; decoder
Ok(decompressed) .read_to_string(&mut decompressed)
.expect("Unablew to decompress data to string");
decompressed
} }
/// Load a pre-compressed test result to a string for comparison in an assert macro /// Load a pre-compressed test result to a string for comparison in an assert macro
pub fn load_compressed_file_to_string(source: &Path) -> String { pub fn load_compressed_file_to_string(source: &Path) -> String {
let mut compressed_file = File::open(&source).expect(format!("Unable to open compressed file at [{}]", source.display()).as_str()); let mut compressed_file = File::open(&source)
.expect(format!("Unable to open compressed file at [{}]", source.display()).as_str());
let mut compressed_data = Vec::new(); let mut compressed_data = Vec::new();
compressed_file.read_to_end(&mut compressed_data) compressed_file
.read_to_end(&mut compressed_data)
.expect(format!("Unable to read compressed data from [{}]", source.display()).as_str()); .expect(format!("Unable to read compressed data from [{}]", source.display()).as_str());
TestCompression::decompress_to_string(&compressed_data).unwrap() TestCompression::decompress_to_string(&compressed_data)
} }
/// Save a str to a specified file as compressed data /// Save a str to a specified file as compressed data
@@ -40,84 +45,68 @@ impl TestCompression {
.truncate(true) // optional: clear existing contents .truncate(true) // optional: clear existing contents
.create(true) .create(true)
.open(target_file) .open(target_file)
.expect(&format!("Unable to open target file [{}] for writing", target_file.display())); .expect(&format!(
"Unable to open target file [{}] for writing",
target_file.display()
));
let compressed_data = TestCompression::compress_string(source); let compressed_data = TestCompression::compress_string(source);
compressed_file.write_all(&compressed_data).expect(&format!(
"Unable to write compressed data to [{}]",
target_file.display()
));
}
pub fn compress_file<P: AsRef<Path>>(source: P, destination: P) -> io::Result<()> {
// Read the source file
let mut read_buffer = String::new();
let mut read_file = File::open(&source)?;
read_file.read_to_string(&mut read_buffer)?;
// Compress the data
let compressed_data = TestCompression::compress_string(&read_buffer);
// Write the compressed data to the destination file
let mut write_file = File::create(&destination)?;
write_file.write_all(&compressed_data)?;
Ok(())
}
pub fn compress_string_to_file(text: &str, target: &Path) {
let compressed_text = TestCompression::compress_string(text);
let mut writer = File::create(target).expect("Unable to create target file.");
writer
.write_all(&compressed_text)
.expect("Unable to write compressed data");
}
pub fn decompress_file_to_string(source: &Path) -> String {
let mut compressed_file = File::open(source).expect("Unable to open source to compress.");
let mut compressed_data = Vec::new();
compressed_file compressed_file
.write_all(&compressed_data) .read_to_end(&mut compressed_data)
.expect(&format!("Unable to write compressed data to [{}]", target_file.display())); .expect("Unable to read compressed data");
} TestCompression::decompress_to_string(&compressed_data)
} }
#[cfg(test)] pub fn compress_file_to_array(file_to_compress: &Path) -> Vec<u8> {
mod tests { let mut read_buffer = String::new();
use tempfile::NamedTempFile; let mut file = File::open(file_to_compress).unwrap();
use super::*; file.read_to_string(&mut read_buffer)
.expect("Unable to read data to compress");
#[test] TestCompression::compress_string(&read_buffer)
fn smoke() { }
assert!(true)
} pub fn decompress_file_to_array(to_decompress: &Path) -> Vec<u8> {
// println!("DECOMPRESS_FILE_TO_ARRAY--> {:?}", to_decompress);
#[test] let file = File::open(to_decompress).expect("Failed to open file");
fn compression_round_trip() { let mut decoder = DeflateDecoder::new(file);
let to_compress = "The quick brown fox jumps over the lazy dog."; let mut output = Vec::new();
decoder
let compressed_text = TestCompression::compress_string(to_compress); .read_to_end(&mut output)
let decompressed_text = TestCompression::decompress_to_string(&compressed_text).unwrap(); .expect("Failed to decompress");
assert_eq!(to_compress, decompressed_text); output
}
#[test]
fn file_compression_round_trip() {
// compress string to file...
let string_to_compress = "The quick brown fox jumps over the lazy dog.";
let compressed_string = TestCompression::compress_string(string_to_compress);
let mut temp_target = NamedTempFile::new().unwrap();
let mut temp_reader = temp_target.reopen();
// ...write the compressed version to a file...
temp_target.write_all(&compressed_string).expect("Unable to write compressed file for test");
//
// ...decompress from file...
let mut compressed_read = Vec::new();
temp_reader.unwrap().read_to_end(&mut compressed_read).expect("Unable to read compressed data for test");
let decompresed = TestCompression::decompress_to_string(&compressed_read).expect("Unable to decompress string for test");
//
// ...verify its the same.
assert_eq!(
string_to_compress,
decompresed
);
}
#[test]
fn file_compression_reader() {
// Get the 'sample text'
let to_compress = "The quick brown fox jumps over the lazy dog.";
// ...write it to the temp file...
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test");
temp_file.write_all(&*TestCompression::compress_string(to_compress)).expect("Unable to write compressed data to temp file for test");
let temp2_path = temp_file.path();
let uncompressed_text = TestCompression::load_compressed_file_to_string(temp2_path);
assert_eq!(uncompressed_text, to_compress);
}
#[test]
fn file_compression_writer() {
let to_compress = "The quick brown fox jumps over the lazy dog.";
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test.");
TestCompression::save_string_as_compressed_data(to_compress, temp_file.path());
// read back the compressed text
let mut read_buffer = Vec::new();
temp_file.read_to_end(&mut read_buffer).expect("Unable to read compressed data back.");
let decompressed_text = TestCompression::decompress_to_string(&read_buffer).expect("Unable to decompress text");
assert_eq!(
decompressed_text,
to_compress);
} }
} }
+1
View File
@@ -0,0 +1 @@
mod poc;
-99
View File
@@ -1,99 +0,0 @@
use std::collections::BTreeMap;
use trevors_utilities::number_system_conversion::NumberSystemConversion;
#[test]
fn byte_to_bool_and_bool_to_byte() {
// confirm a byte becomes a valid bool
// **** NOTE THAT THIS VISUALLY IS BACKWARDS AS INDEX 0 IS FIRST AND LSB IS LAST ****
let test_params: BTreeMap<u8, [bool; 8]> = BTreeMap::from([
(0xff, [true, true, true, true, true, true, true, true]),
(0x00, [false, false, false, false, false, false, false, false]),
(0xa0, [false, false, false, false, false, true, false, true])
]);
for (src, dst) in test_params {
assert_eq!(
dst,
NumberSystemConversion::byte_to_bool(src),
"Unable to convert [{}] to [{:?}]", src, dst
);
assert_eq!(
src,
NumberSystemConversion::bool_to_byte(dst),
"Unable to convert [{:?}] to [{}]", dst, src
);
assert_eq!(
src,
NumberSystemConversion::bool_to_byte(
NumberSystemConversion::byte_to_bool(src))
);
}
}
#[test]
fn swap_endianness_u16() {
let test_params: Vec<(u16, u16)> = vec![(0xabcd, 0xcdab), (0x0000, 0x0000), (0xffff, 0xffff), (0x00ff, 0xff00)];
for (src, dst) in test_params {
assert_eq!(src, NumberSystemConversion::swap_endian_u16(dst));
assert_eq!(src, NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(src)));
assert_eq!(dst, NumberSystemConversion::swap_endian_u16(src));
assert_eq!(dst, NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(dst)));
}
}
#[test]
fn swap_endinness_u32() {
let test_params: Vec<(u32, u32)> = vec![
(0xabcdef01, 0x01efcdab),
(0x12345678, 0x78563412),
(0xbadbeef0, 0xf0eedbba)
];
for (src, dst) in test_params {
assert_eq!(src, NumberSystemConversion::swap_endian_u32(dst));
assert_eq!(src, NumberSystemConversion::swap_endian_u32(
NumberSystemConversion::swap_endian_u32(src)));
assert_eq!(dst, NumberSystemConversion::swap_endian_u32(src));
assert_eq!(dst, NumberSystemConversion::swap_endian_u32(
NumberSystemConversion::swap_endian_u32(dst)));
}
}
#[test]
fn split_bytes_u16_join_bytes_u16() {
let test_params = BTreeMap::from([
(0x0000, (0x00, 0x00)),
(0xabcd, (0xab, 0xcd)),
(0xffff, (0xff, 0xff)),
(0xbeef, (0xbe, 0xef))
]);
for (joined, (high, low)) in test_params {
assert_eq!(
(high, low),
NumberSystemConversion::split_bytes_u16(joined));
assert_eq!(
joined,
NumberSystemConversion::join_bytes_u16_from_u8(high, low));
assert_eq!(
joined,
NumberSystemConversion::join_bytes_u16(high as u16, low as u16));
}
}
#[test]
fn combine_u8_to_u16() {
let test_params: Vec<((u8, u8), u16)> = vec![
((0xff, 0x00), 0x00ff),
((0x00, 0xff), 0xff00),
((0xbe, 0xef), 0xefbe),
((0xef, 0xbe), 0xbeef)
];
for ((low, high), base) in test_params {
assert_eq!(
base, NumberSystemConversion::combine_u8_to_u16(low, high)
)
}
}
+73
View File
@@ -0,0 +1,73 @@
use trevors_utilities::data_to_text::DataToText;
fn read_bin(source: &str) -> Vec<u8> {
let full_path = format!(
"{}/resources/data_to_text/{}.bin",
std::env::current_dir()
.unwrap()
.to_str()
.unwrap()
.to_string(),
source
);
// println!("FULL PATH BIN: [{}]", full_path);
std::fs::read(full_path).unwrap()
}
fn read_display(source: &str) -> String {
let full_path = format!(
"{}/resources/data_to_text/{}.display",
std::env::current_dir()
.unwrap()
.to_str()
.unwrap()
.to_string(),
source
);
std::fs::read_to_string(full_path).unwrap()
}
#[test]
fn data_to_text() {
let data_to_display: &[u8] = &[
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
0x20, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x20,
];
let expected_data: &str = "0x66 0x67 0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71 0x72 0x73 0x74 0x20 fghijklmnopqrst \n0x76 0x77 0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f 0x20 vwxyz{|}~ \n";
let actual_data = DataToText::data_to_text(data_to_display);
assert_eq!(actual_data, expected_data);
}
#[test]
fn quickbrownfoxtest() {
let test_params = vec!["quickbrownfox", "q"];
for stub in test_params {
// load the content from quickbrownfox.bin
let bin_data = read_bin(stub);
// format it for display
let formatted = DataToText::data_to_text(&bin_data);
// load the content from quickbrownfox.display
let expected = read_display(stub);
assert_eq!(formatted, expected);
}
}
#[test]
fn data_to_text_window_all() {
let bin_data = read_bin("quickbrownfox");
let formatted = DataToText::data_to_text_window(&bin_data, 0, bin_data.len());
let expected = read_display("quickbrownfox");
assert_eq!(formatted, expected);
}
#[test]
fn test_window_past_end_of_data() {
let bin_data = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
let formatted = DataToText::data_to_text_window(&bin_data, 10, 10);
assert_eq!(formatted, "");
}
+16
View File
@@ -0,0 +1,16 @@
use trevors_utilities::format_with_commas::format_with_commas;
#[test]
fn format_with_commas_none_needed() {
assert_eq!("0", format_with_commas(0));
}
#[test]
fn format_thousands() {
assert_eq!("1,000", format_with_commas(1000));
}
#[test]
fn format_millions() {
assert_eq!("1,000,000", format_with_commas(1000000));
}
+5
View File
@@ -0,0 +1,5 @@
mod data_to_text;
mod number_system_conversion;
mod test_compression;
mod format_with_commas;
mod primitive_formatting;
+200
View File
@@ -0,0 +1,200 @@
use std::collections::BTreeMap;
use trevors_utilities::number_system_conversion::NumberSystemConversion;
#[test]
fn byte_to_bool_and_bool_to_byte() {
// confirm a byte becomes a valid bool
// **** NOTE THAT THIS VISUALLY IS BACKWARDS AS INDEX 0 IS FIRST AND LSB IS LAST ****
let test_params: BTreeMap<u8, [bool; 8]> = BTreeMap::from([
(0xff, [true, true, true, true, true, true, true, true]),
(
0x00,
[false, false, false, false, false, false, false, false],
),
(0xa0, [false, false, false, false, false, true, false, true]),
]);
for (src, dst) in test_params {
assert_eq!(
dst,
NumberSystemConversion::byte_to_bool(src),
"Unable to convert [{}] to [{:?}]",
src,
dst
);
assert_eq!(
src,
NumberSystemConversion::bool_to_byte(dst),
"Unable to convert [{:?}] to [{}]",
dst,
src
);
assert_eq!(
src,
NumberSystemConversion::bool_to_byte(NumberSystemConversion::byte_to_bool(src))
);
}
}
#[test]
fn swap_endianness_u16() {
let test_params: Vec<(u16, u16)> = vec![
(0xabcd, 0xcdab),
(0x0000, 0x0000),
(0xffff, 0xffff),
(0x00ff, 0xff00),
];
for (src, dst) in test_params {
assert_eq!(src, NumberSystemConversion::swap_endian_u16(dst));
assert_eq!(
src,
NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(src))
);
assert_eq!(dst, NumberSystemConversion::swap_endian_u16(src));
assert_eq!(
dst,
NumberSystemConversion::swap_endian_u16(NumberSystemConversion::swap_endian_u16(dst))
);
}
}
#[test]
fn swap_endinness_u32() {
let test_params: Vec<(u32, u32)> = vec![
(0xabcdef01, 0x01efcdab),
(0x12345678, 0x78563412),
(0xbadbeef0, 0xf0eedbba),
];
for (src, dst) in test_params {
assert_eq!(src, NumberSystemConversion::swap_endian_u32(dst));
assert_eq!(
src,
NumberSystemConversion::swap_endian_u32(NumberSystemConversion::swap_endian_u32(src))
);
assert_eq!(dst, NumberSystemConversion::swap_endian_u32(src));
assert_eq!(
dst,
NumberSystemConversion::swap_endian_u32(NumberSystemConversion::swap_endian_u32(dst))
);
}
}
#[test]
fn split_bytes_u16_join_bytes_u16() {
let test_params = BTreeMap::from([
(0x0000, (0x00, 0x00)),
(0xabcd, (0xab, 0xcd)),
(0xffff, (0xff, 0xff)),
(0xbeef, (0xbe, 0xef)),
]);
for (joined, (high, low)) in test_params {
assert_eq!((high, low), NumberSystemConversion::split_bytes_u16(joined));
assert_eq!(
joined,
NumberSystemConversion::join_bytes_u16(high as u16, low as u16)
);
}
}
#[test]
fn combine_u8_to_u16() {
let test_params: Vec<((u8, u8), u16)> = vec![
((0xff, 0x00), 0x00ff),
((0x00, 0xff), 0xff00),
((0xbe, 0xef), 0xefbe),
((0xef, 0xbe), 0xbeef),
];
for ((low, high), base) in test_params {
assert_eq!(base, NumberSystemConversion::combine_u8_to_u16(low, high))
}
}
#[test]
fn clear_high_bits() {
let test_params = vec![
(0b1111_1111_0101_1010, 0b0000_0000_0101_1010),
(0b1111_1111_1111_1111, 0b0000_0000_1111_1111),
(0b0000_0000_1111_1111, 0b0000_0000_1111_1111),
(0b0101_1010_1001_0110, 0b0000_0000_1001_0110),
];
for (src, dst) in test_params {
let result = NumberSystemConversion::clear_high_bits(src);
println!("Rolled {src:016b} to {result:016b} / {dst:016b}");
assert_eq!(NumberSystemConversion::clear_high_bits(src), dst);
}
}
#[test]
fn clear_low_bits() {
let test_params = vec![
(0b1111_1111_0101_1010, 0b1111_1111_0000_0000),
(0b1111_1111_1111_1111, 0b1111_1111_0000_0000),
(0b0000_0000_1111_1111, 0b0000_0000_0000_0000),
(0b0101_1010_1001_0110, 0b0101_1010_0000_0000),
];
for (src, dst) in test_params {
let result = NumberSystemConversion::clear_low_bits(src);
println!("Rolled {src:08b} to {result:08b} / {dst:08b}");
assert_eq!(NumberSystemConversion::clear_low_bits(src), dst);
}
}
#[test]
fn is_bit_set_checks() {
let params = vec![
(
0b0000_0001,
vec![true, false, false, false, false, false, false, false],
),
(
0b1111_1111,
vec![true, true, true, true, true, true, true, true],
),
(
0b1010_1010,
vec![false, true, false, true, false, true, false, true],
),
];
for (base, options) in params {
for (index, expected) in options.iter().enumerate() {
assert_eq!(
*expected,
NumberSystemConversion::is_bit_set(base, index as u8)
);
}
}
}
#[test]
fn is_bit_clear_checks() {
let params = vec![
(
0b0000_0001,
vec![false, true, true, true, true, true, true, true],
),
(
0b1111_1111,
vec![false, false, false, false, false, false, false, false],
),
(
0b1010_1010,
vec![true, false, true, false, true, false, true, false],
),
];
for (base, options) in params {
for (index, expected) in options.iter().enumerate() {
assert_eq!(
*expected,
NumberSystemConversion::is_bit_clear(base, index as u8)
);
}
}
}
+7
View File
@@ -0,0 +1,7 @@
use trevors_utilities::primitive_formatting;
#[test]
fn test_primitive_bool() {
assert_eq!("1".to_string(), primitive_formatting::bool_to_string(true));
assert_eq!("0".to_string(), primitive_formatting::bool_to_string(false));
}
+182
View File
@@ -0,0 +1,182 @@
use std::io::{Read, Write};
use tempfile::NamedTempFile;
use trevors_utilities::test_compression::TestCompression;
#[cfg(test)]
mod tests {
const SAMPLE_TEXT: &str = "The quick brown fox jumps over the lazy dog.";
use super::*;
#[test]
fn smoke() {
assert!(true)
}
#[test]
fn compression_round_trip() {
let to_compress = SAMPLE_TEXT;
let decompressed_text =
TestCompression::decompress_to_string(&TestCompression::compress_string(to_compress));
assert_eq!(to_compress, decompressed_text);
}
#[test]
fn file_compression_round_trip() {
// compress string to file...
let string_to_compress = SAMPLE_TEXT;
let compressed_string = TestCompression::compress_string(string_to_compress);
let mut temp_target = NamedTempFile::new().unwrap();
let temp_reader = temp_target.reopen();
// ...write the compressed version to a file...
temp_target
.write_all(&compressed_string)
.expect("Unable to write compressed file for test");
//
// ...decompress from file...
let mut compressed_read = Vec::new();
temp_reader
.unwrap()
.read_to_end(&mut compressed_read)
.expect("Unable to read compressed data for test");
let decompresed = TestCompression::decompress_to_string(&compressed_read);
//
// ...verify its the same.
assert_eq!(string_to_compress, decompresed);
}
#[test]
fn file_compression_reader() {
// Get the 'sample text'
let to_compress = SAMPLE_TEXT;
// ...write it to the temp file...
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test");
temp_file
.write_all(&*TestCompression::compress_string(to_compress))
.expect("Unable to write compressed data to temp file for test");
let temp2_path = temp_file.path();
let uncompressed_text = TestCompression::load_compressed_file_to_string(temp2_path);
assert_eq!(uncompressed_text, to_compress);
}
#[test]
fn file_compression_writer() {
let to_compress = SAMPLE_TEXT;
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test.");
TestCompression::save_string_as_compressed_data(to_compress, temp_file.path());
// read back the compressed text
let mut read_buffer = Vec::new();
temp_file
.read_to_end(&mut read_buffer)
.expect("Unable to read compressed data back.");
let decompressed_text = TestCompression::decompress_to_string(&read_buffer);
assert_eq!(decompressed_text, to_compress);
}
#[test]
fn compress_file() {
// create our test file.
let test_text = SAMPLE_TEXT;
let mut original_file = NamedTempFile::new().unwrap();
let compressed_file = NamedTempFile::new().unwrap();
original_file
.write(test_text.as_bytes())
.expect("Unable to write original file");
// run the method being tested
TestCompression::compress_file(original_file.path(), compressed_file.path())
.expect("Unable to compress temp file.");
// verify the data in the new file matches what we expect
let mut reader_file = compressed_file.reopen().unwrap();
let mut result_text = Vec::new();
reader_file
.read_to_end(&mut result_text)
.expect("Unable to read compressed data back to verify");
let decompressed_text = TestCompression::decompress_to_string(&result_text);
assert_eq!(decompressed_text, test_text);
}
#[test]
fn compress_string_to_file() {
let to_compress = SAMPLE_TEXT;
let compressed_text = TestCompression::compress_string(to_compress);
let target_file = NamedTempFile::new().unwrap();
let mut duplicate = target_file.reopen().unwrap();
TestCompression::compress_string_to_file(to_compress, target_file.path());
let mut file_contents = Vec::new();
duplicate
.read_to_end(&mut file_contents)
.expect("Unable to read compressed file.");
assert_eq!(file_contents, compressed_text);
}
#[test]
fn decompress_file_to_string() {
let to_compress = SAMPLE_TEXT;
let temp = NamedTempFile::new().unwrap();
TestCompression::compress_string_to_file(to_compress, temp.path());
let result = TestCompression::decompress_file_to_string(temp.path());
assert_eq!(to_compress, result);
}
#[test]
fn compress_file_to_array() {
let to_compress = SAMPLE_TEXT;
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test");
temp_file.write_all(to_compress.as_bytes()).unwrap();
let result = TestCompression::compress_file_to_array(temp_file.path());
let decompressed_result = TestCompression::decompress_to_string(&result);
assert_eq!(to_compress, decompressed_result);
}
#[test]
fn compress_file_to_array_with_trailing_newline() {
let to_compress = format!("{}\n", SAMPLE_TEXT);
let mut temp_file = NamedTempFile::new().expect("Unable to get temp file for test");
temp_file.write_all(to_compress.as_bytes()).unwrap();
let result = TestCompression::compress_file_to_array(temp_file.path());
let decompressed_result = TestCompression::decompress_to_string(&result);
assert_eq!(to_compress, decompressed_result);
}
#[test]
fn decompress_to_array() {
let original_text = SAMPLE_TEXT;
let compressed_data = TestCompression::compress_string(original_text);
// Write the compressed data to a temp file
let mut temp_file = NamedTempFile::new().expect("Failed to create temp file");
temp_file
.write_all(&compressed_data)
.expect("Failed to write compressed data to file");
// Run the method under test
let decompressed_data = TestCompression::decompress_file_to_array(temp_file.path());
// Convert to string to compare
let decompressed_text =
String::from_utf8(decompressed_data).expect("Decompressed bytes were not valid UTF-8");
assert_eq!(decompressed_text, original_text);
}
#[test]
#[should_panic(expected = "No such file or directory")]
fn decompress_file_panics_on_missing_path() {
let bad_path = std::path::Path::new("/definitely/invalid/path");
TestCompression::decompress_file_to_array(bad_path);
}
}