diff --git a/Cargo.lock b/Cargo.lock index ae69060b..71806af0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" @@ -52,20 +52,11 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -78,43 +69,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys 0.59.0", ] [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -123,45 +115,34 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -172,9 +153,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" @@ -184,9 +165,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "block-buffer" @@ -208,15 +189,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytes" -version = "1.6.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cbc" @@ -229,9 +210,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.100" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c891175c3fb232128f48de6590095e59198bbeb8620c310be349bfc3afd12c7b" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +dependencies = [ + "shlex", +] [[package]] name = "cesu8" @@ -241,20 +225,26 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.5", + "windows-link", ] [[package]] @@ -269,24 +259,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap" -version = "4.5.7" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -294,23 +269,23 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -318,15 +293,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -344,26 +319,36 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -386,9 +371,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -408,15 +393,15 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -429,9 +414,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -439,15 +424,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -456,15 +441,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -473,21 +458,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -513,9 +498,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -524,15 +509,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "heck" @@ -542,18 +521,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hmac" @@ -566,14 +536,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -589,9 +560,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "block-padding", "generic-array", @@ -607,17 +578,28 @@ dependencies = [ "mach2", ] +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "libc", +] + [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jni" @@ -629,7 +611,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -641,10 +623,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -656,70 +639,61 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "log" -version = "0.4.21" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memoffset" -version = "0.7.1" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "mio-serial" -version = "5.0.5" +version = "5.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20a4c60ca5c9c0e114b3bd66ff4aa5f9b2b175442be51ca6c4365d687a97a2ac" +checksum = "029e1f407e261176a983a6599c084efd322d9301028055c87174beac71397ba3" dependencies = [ "log", "mio", - "nix", + "nix 0.29.0", "serialport", "winapi", ] @@ -733,8 +707,18 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset", - "pin-utils", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "cfg_aliases", + "libc", ] [[package]] @@ -758,46 +742,52 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] [[package]] name = "object" -version = "0.36.0" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +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 = "oo-bindgen" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f5f798c35376fe2c8cdf364aa0a848f54330646a551100aa6273fa7c1156b8" +checksum = "c87847ac8cd3f9ff4bfdb3a23ce104225f7246f37ac1567efe6fc528bb26563b" dependencies = [ "backtrace", - "clap 4.5.7", + "clap", "dunce", - "heck 0.4.1", + "heck", "lazy_static", "platforms", "regex", "semver", "serde", "serde_json", - "thiserror", + "thiserror 2.0.12", "tracing", ] @@ -819,9 +809,9 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" dependencies = [ "base64", "serde", @@ -838,9 +828,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -883,18 +873,18 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -907,9 +897,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -919,9 +909,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -930,21 +920,20 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -953,7 +942,7 @@ dependencies = [ name = "rodbus" version = "1.4.0" dependencies = [ - "clap 4.5.7", + "clap", "crc", "rx509", "scursor", @@ -983,8 +972,9 @@ dependencies = [ name = "rodbus-client" version = "1.4.0" dependencies = [ - "clap 2.34.0", + "clap", "rodbus", + "thiserror 2.0.12", "tokio", "tracing", "tracing-subscriber", @@ -1029,42 +1019,62 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustls" -version = "0.23.10" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.3", "subtle", "zeroize", ] [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "ring", "rustls-pki-types", "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + [[package]] name = "rx509" version = "0.2.1" @@ -1073,9 +1083,9 @@ checksum = "d3b4a7d26e4a603b3cedff6a968d356e445c10dbc3e4cf6bd414fd5428437e73" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa20" @@ -1120,24 +1130,24 @@ checksum = "49e9e097d5ccc66dd9a88d94c7ddad0833b13a35ed8f30d6ea28a8d5269cbd58" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1146,28 +1156,29 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serialport" -version = "4.3.0" +version = "4.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828" +checksum = "cdb0bc984f6af6ef8bab54e6cf2071579ee75b9286aa9f2319a0d220c28b0a2b" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.9.1", "cfg-if", + "core-foundation", "core-foundation-sys", "io-kit-sys", "mach2", - "nix", - "regex", + "nix 0.26.4", "scopeguard", "unescaper", "winapi", @@ -1188,7 +1199,7 @@ dependencies = [ "pem", "pkcs8", "rustls", - "rustls-webpki", + "rustls-webpki 0.102.8", "rx509", ] @@ -1221,9 +1232,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -1239,37 +1250,34 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" version = "0.7.3" @@ -1280,12 +1288,6 @@ dependencies = [ "der", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.11.1" @@ -1300,9 +1302,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.68" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1310,28 +1312,39 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "unicode-width", + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "1.0.61" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.12", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -1340,36 +1353,36 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] name = "tokio" -version = "1.38.0" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", - "num_cpus", "pin-project-lite", + "slab", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -1378,33 +1391,33 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] [[package]] name = "tokio-serial" -version = "5.4.4" +version = "5.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa6e2e4cf0520a99c5f87d5abb24172b5bd220de57c3181baaaa5440540c64aa" +checksum = "aa1d5427f11ba7c5e6384521cfd76f2d64572ff29f3f4f7aa0f496282923fdc8" dependencies = [ "cfg-if", "futures", "log", "mio-serial", + "serialport", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -1426,9 +1439,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -1439,9 +1452,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1450,9 +1463,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", @@ -1461,9 +1474,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -1482,9 +1495,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -1492,9 +1505,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "chrono", "nu-ansi-term", @@ -1510,30 +1523,24 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unescaper" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" dependencies = [ - "thiserror", + "thiserror 2.0.12", ] [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-width" -version = "0.1.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "untrusted" @@ -1549,21 +1556,15 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vec_map" -version = "0.8.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" @@ -1577,29 +1578,30 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1608,9 +1610,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1618,9 +1620,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -1631,9 +1633,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "winapi" @@ -1653,11 +1658,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1668,151 +1673,144 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-targets 0.52.5", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-implement" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ - "windows-targets 0.48.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ - "windows-targets 0.52.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-link", ] [[package]] -name = "windows-targets" -version = "0.52.5" +name = "windows-strings" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows-link", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +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_msvc" -version = "0.52.5" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_i686_gnu" -version = "0.48.5" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "zeroize" diff --git a/rodbus-client/Cargo.toml b/rodbus-client/Cargo.toml index 45c14bdf..7f1c7cca 100644 --- a/rodbus-client/Cargo.toml +++ b/rodbus-client/Cargo.toml @@ -22,8 +22,9 @@ name = "rodbus-client" path = "src/main.rs" [dependencies] -rodbus = { path = "../rodbus", default-features = false } -clap = "2.33" +rodbus = { path = "../rodbus", default-features = false, features = ["serial"]} +clap = { version = "4.0", features = ["derive"] } tokio = { workspace = true, features = ["macros", "time"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } +thiserror = { version = "2.0.12" } diff --git a/rodbus-client/src/main.rs b/rodbus-client/src/main.rs index 49a36071..dfde4139 100644 --- a/rodbus-client/src/main.rs +++ b/rodbus-client/src/main.rs @@ -1,60 +1,254 @@ //! Command-line Modbus client -use std::fmt::Formatter; use std::net::{AddrParseError, SocketAddr}; use std::num::ParseIntError; use std::str::{FromStr, ParseBoolError}; use std::time::Duration; -use clap::{App, Arg, ArgMatches, SubCommand}; +use clap::{Args, Parser, Subcommand}; use rodbus::client::*; use rodbus::*; use rodbus::{InvalidRange, InvalidRequest, Shutdown}; +use thiserror::Error; -#[derive(Debug)] +const CHANNEL_BUFFER_SIZE: usize = 32; +const REQUEST_TIMEOUT: Duration = Duration::from_secs(1); +const MAX_QUEUED_REQUESTS: usize = 1; + +#[derive(Debug, Error)] enum Error { + #[error("Errors that can be produced when validating start/count")] BadRange(InvalidRange), + #[error("The provided string cannot be parsed into a address: {0}")] BadAddr(std::net::AddrParseError), + #[error("Cannot parse this value as an integer")] BadInt(std::num::ParseIntError), + #[error("An error returned when parsing a bool using [from_str] fails")] BadBool(std::str::ParseBoolError), + #[error("Bad character in bit string: {0}")] BadCharInBitString(char), + #[error("Request error: {0}")] Request(rodbus::RequestError), - MissingSubCommand, + #[error("Channel was shutdown")] Shutdown, + #[error("Unable to connect: {0}")] + UnableToConnect(String), +} + +#[derive(Parser)] +#[command(name = "rodbus-client")] +#[command( + about = "A command line program for making Modbus client requests using the Rodbus crate" +)] +#[command(version = "1.4.0")] +struct Cli { + #[arg( + short = 'i', + long, + default_value = "1", + help = "The unit id of Modbus server" + )] + id: u8, + + #[arg(short = 'p', long, help = "Optional polling period in milliseconds")] + period: Option, + + #[command(subcommand)] + mode: Mode, +} + +#[derive(Subcommand)] +enum Mode { + #[command(name = "tcp", about = "use the TCP protocol")] + Tcp { + #[arg(long, default_value = "127.0.0.1:502", help = "address of the socket")] + host: SocketAddr, + + #[command(subcommand)] + command: Command, + }, + #[command(name = "serial", about = "use the serial protocol")] + Serial { + #[command(flatten)] + settings: ModeSerialSettings, + + #[arg(short = 'p', long, help = "the serial port path")] + path: String, + + #[command(subcommand)] + command: Command, + }, +} + +/// Settings for initializing a serial connection +#[derive(Clone, Args, Copy)] +struct ModeSerialSettings { + #[arg( + short = 'b', + long, + default_value = "9600", + help = "baud rate of the device" + )] + baud_rate: u32, + #[arg(short = 'd', long, default_value = "8", help = "data bits of the device", value_parser = parse_data_bits )] + data_bits: DataBits, + #[arg(short = 'f', long, default_value = "none", help = "flow control of the device", value_parser = parse_flow_control)] + flow_control: FlowControl, + #[arg(short = 's', long, default_value = "1", help = "stop bits of the device", value_parser = parse_stop_bits)] + stop_bits: StopBits, + #[arg(long, default_value = "none", help = "parity of the device", value_parser = parse_parity)] + parity: Parity, +} + +impl From for SerialSettings { + fn from(settings: ModeSerialSettings) -> Self { + Self { + baud_rate: settings.baud_rate, + data_bits: settings.data_bits, + flow_control: settings.flow_control, + stop_bits: settings.stop_bits, + parity: settings.parity, + } + } +} + +fn parse_data_bits(s: &str) -> Result { + match s { + "5" => Ok(DataBits::Five), + "6" => Ok(DataBits::Six), + "7" => Ok(DataBits::Seven), + "8" => Ok(DataBits::Eight), + _ => Err(format!("invalid data bits: {s}")), + } } +fn parse_flow_control(s: &str) -> Result { + match s { + "none" => Ok(FlowControl::None), + "software" => Ok(FlowControl::Software), + "hardware" => Ok(FlowControl::Hardware), + _ => Err(format!( + "invalid flow control: {s}, expected one of: none, software, hardware" + )), + } +} + +fn parse_stop_bits(s: &str) -> Result { + match s { + "1" => Ok(StopBits::One), + "2" => Ok(StopBits::Two), + _ => Err(format!("invalid stop bits: {s}, expected one of: 1, 2")), + } +} + +fn parse_parity(s: &str) -> Result { + match s { + "none" => Ok(Parity::None), + "odd" => Ok(Parity::Odd), + "even" => Ok(Parity::Even), + _ => Err(format!( + "invalid parity: {s}, expected one of: none, odd, even" + )), + } +} + +#[derive(Subcommand)] enum Command { - ReadCoils(AddressRange), - ReadDiscreteInputs(AddressRange), - ReadHoldingRegisters(AddressRange), - ReadInputRegisters(AddressRange), - WriteSingleRegister(Indexed), - WriteSingleCoil(Indexed), - WriteMultipleCoils(WriteMultiple), - WriteMultipleRegisters(WriteMultiple), + #[command(name = "rc", about = "read coils")] + ReadCoils(ReadArgs), + + #[command(name = "rdi", about = "read discrete inputs")] + ReadDiscreteInputs(ReadArgs), + + #[command(name = "rhr", about = "read holding registers")] + ReadHoldingRegisters(ReadArgs), + + #[command(name = "rir", about = "read input registers")] + ReadInputRegisters(ReadArgs), + + #[command(name = "wsc", about = "write single coil")] + WriteSingleCoil(WriteSingleCoilArgs), + + #[command(name = "wsr", about = "write single register")] + WriteSingleRegister(WriteSingleRegisterArgs), + + #[command(name = "wmc", about = "write multiple coils")] + WriteMultipleCoils(WriteMultipleCoilsArgs), + + #[command(name = "wmr", about = "write multiple registers")] + WriteMultipleRegisters(WriteMultipleRegistersArgs), +} + +#[derive(Args)] +struct ReadArgs { + #[arg(short = 's', long, help = "the starting address")] + start: u16, + + #[arg(short = 'q', long, help = "quantity of values")] + quantity: u16, } -struct Args { - address: SocketAddr, - id: UnitId, - command: Command, - period: Option, +#[derive(Args)] +struct WriteSingleCoilArgs { + #[arg(short = 'i', long, help = "the address of the coil")] + index: u16, + + #[arg(short = 'v', long, help = "the value of the coil (ON or OFF)")] + value: bool, +} + +#[derive(Args)] +struct WriteSingleRegisterArgs { + #[arg(short = 'i', long, help = "the address of the register")] + index: u16, + + #[arg(short = 'v', long, help = "the value of the register")] + value: u16, } -struct ConnectionListener { - tx: tokio::sync::mpsc::Sender, +#[derive(Args)] +struct WriteMultipleCoilsArgs { + #[arg(short = 's', long, help = "the starting address of the coils")] + start: u16, + + #[arg( + short = 'v', + long, + help = "the values of the coils specified as a string of 1 and 0 (e.g. 10100011)" + )] + values: String, } -impl ConnectionListener { - fn create() -> (Self, tokio::sync::mpsc::Receiver) { - let (tx, rx) = tokio::sync::mpsc::channel(32); +#[derive(Args)] +struct WriteMultipleRegistersArgs { + #[arg(short = 's', long, help = "the starting address of the registers")] + start: u16, + + #[arg( + short = 'v', + long, + help = "the values of the registers specified as a comma delimited list (e.g. 1,4,7)" + )] + values: String, +} + +struct StateListener { + tx: tokio::sync::mpsc::Sender, +} + +impl StateListener { + fn create() -> (Self, tokio::sync::mpsc::Receiver) { + let (tx, rx) = tokio::sync::mpsc::channel(CHANNEL_BUFFER_SIZE); (Self { tx }, rx) } } -impl Listener for ConnectionListener { - fn update(&mut self, state: ClientState) -> MaybeAsync<()> { +impl Listener for StateListener +where + T: Send + 'static, +{ + fn update(&mut self, state: T) -> MaybeAsync<()> { let tx = self.tx.clone(); let future = async move { let _ = tx.try_send(state); @@ -63,19 +257,8 @@ impl Listener for ConnectionListener { } } -impl Args { - fn new(address: SocketAddr, id: UnitId, command: Command, period: Option) -> Self { - Self { - address, - id, - command, - period, - } - } -} - #[tokio::main(flavor = "multi_thread")] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), Error> { // Initialize logging tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) @@ -89,18 +272,54 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn run() -> Result<(), Box> { - let args = parse_args()?; +async fn run() -> Result<(), Error> { + let cli = Cli::parse(); + + let (mut channel, command) = setup_channel(cli.mode).await?; + + let params = RequestParam::new(UnitId::new(cli.id), REQUEST_TIMEOUT); + + match cli.period { + None => run_command(&command, &mut channel, params).await, + Some(period_ms) => { + let period = Duration::from_millis(period_ms); + loop { + run_command(&command, &mut channel, params).await?; + tokio::time::sleep(period).await + } + } + } +} + +async fn setup_channel(mode: Mode) -> Result<(Channel, Command), Error> { + let (channel, command) = match mode { + Mode::Tcp { host, command } => { + let channel = setup_tcp(host).await?; + (channel, command) + } + Mode::Serial { + path, + settings, + command, + } => { + let channel = setup_serial(path, settings).await?; + (channel, command) + } + }; - let (listener, mut rx) = ConnectionListener::create(); + Ok((channel, command)) +} - let mut channel = spawn_tcp_client_task( - HostAddr::ip(args.address.ip(), args.address.port()), - 1, +async fn setup_tcp(host: SocketAddr) -> Result { + let (listener, mut rx) = StateListener::create(); + let channel = spawn_tcp_client_task( + HostAddr::ip(host.ip(), host.port()), + MAX_QUEUED_REQUESTS, default_retry_strategy(), AppDecodeLevel::DataValues.into(), Some(Box::new(listener)), ); + channel.enable().await?; 'connect: loop { @@ -112,79 +331,97 @@ async fn run() -> Result<(), Box> { _ => return Err("unable to connect".into()), } } + Ok(channel) +} - let params = RequestParam::new(args.id, Duration::from_secs(1)); - - match args.period { - None => run_command(&args.command, &mut channel, params).await, - Some(period) => loop { - run_command(&args.command, &mut channel, params).await?; - tokio::time::sleep(period).await +async fn setup_serial(path: String, settings: ModeSerialSettings) -> Result { + let settings: SerialSettings = settings.into(); + let (listener, mut rx) = StateListener::create(); + let channel = spawn_rtu_client_task( + &path, + settings, + MAX_QUEUED_REQUESTS, + default_retry_strategy(), + DecodeLevel { + app: AppDecodeLevel::DataHeaders, + frame: FrameDecodeLevel::Nothing, + physical: PhysDecodeLevel::Nothing, }, + Some(Box::new(listener)), + ); + + channel.enable().await?; + + 'connect: loop { + let state = rx.recv().await.expect("should never be empty"); + tracing::info!("state: {state:?}"); + match state { + PortState::Disabled | PortState::Wait(_) => {} + PortState::Open => break 'connect, + PortState::Shutdown => return Err("unable to connect".into()), + } } + + Ok(channel) } async fn run_command( command: &Command, channel: &mut Channel, params: RequestParam, -) -> Result<(), Box> { +) -> Result<(), Error> { match command { - Command::ReadCoils(range) => { - for x in channel.read_coils(params, *range).await? { + Command::ReadCoils(args) => { + let range = AddressRange::try_from(args.start, args.quantity)?; + for x in channel.read_coils(params, range).await? { println!("index: {} value: {}", x.index, x.value) } } - Command::ReadDiscreteInputs(range) => { - for x in channel.read_discrete_inputs(params, *range).await? { + Command::ReadDiscreteInputs(args) => { + let range = AddressRange::try_from(args.start, args.quantity)?; + for x in channel.read_discrete_inputs(params, range).await? { println!("index: {} value: {}", x.index, x.value) } } - Command::ReadHoldingRegisters(range) => { - for x in channel.read_holding_registers(params, *range).await? { + Command::ReadHoldingRegisters(args) => { + let range = AddressRange::try_from(args.start, args.quantity)?; + for x in channel.read_holding_registers(params, range).await? { println!("index: {} value: {}", x.index, x.value) } } - Command::ReadInputRegisters(range) => { - for x in channel.read_input_registers(params, *range).await? { + Command::ReadInputRegisters(args) => { + let range = AddressRange::try_from(args.start, args.quantity)?; + for x in channel.read_input_registers(params, range).await? { println!("index: {} value: {}", x.index, x.value) } } - Command::WriteSingleRegister(arg) => { - channel.write_single_register(params, *arg).await?; + Command::WriteSingleRegister(args) => { + let indexed = Indexed::new(args.index, args.value); + channel.write_single_register(params, indexed).await?; } - Command::WriteSingleCoil(arg) => { - channel.write_single_coil(params, *arg).await?; + Command::WriteSingleCoil(args) => { + let indexed = Indexed::new(args.index, args.value); + channel.write_single_coil(params, indexed).await?; } - Command::WriteMultipleCoils(arg) => { - channel.write_multiple_coils(params, arg.clone()).await?; + Command::WriteMultipleCoils(args) => { + let values = parse_bit_values(&args.values)?; + let write_multiple = WriteMultiple::from(args.start, values)?; + channel.write_multiple_coils(params, write_multiple).await?; } - Command::WriteMultipleRegisters(arg) => { + Command::WriteMultipleRegisters(args) => { + let values = parse_register_values(&args.values)?; + let write_multiple = WriteMultiple::from(args.start, values)?; channel - .write_multiple_registers(params, arg.clone()) + .write_multiple_registers(params, write_multiple) .await?; } } Ok(()) } -fn get_index(arg: &ArgMatches) -> Result { - u16::from_str(arg.value_of("index").unwrap()) -} - -fn get_start(arg: &ArgMatches) -> Result { - u16::from_str(arg.value_of("start").unwrap()) -} - -fn get_value(arg: &ArgMatches) -> Result { - u16::from_str(arg.value_of("value").unwrap()) -} - -fn get_bit_values(arg: &ArgMatches) -> Result, Error> { - let str = arg.value_of("values").unwrap(); - +fn parse_bit_values(values_str: &str) -> Result, Error> { let mut values: Vec = Vec::new(); - for c in str.chars().rev() { + for c in values_str.chars().rev() { match c { '0' => values.push(false), '1' => values.push(true), @@ -194,301 +431,14 @@ fn get_bit_values(arg: &ArgMatches) -> Result, Error> { Ok(values) } -fn get_register_values(arg: &ArgMatches) -> Result, ParseIntError> { - let str = arg.value_of("values").unwrap(); - +fn parse_register_values(values_str: &str) -> Result, ParseIntError> { let mut values: Vec = Vec::new(); - for value in str.split(',') { + for value in values_str.split(',') { values.push(u16::from_str(value)?); } Ok(values) } -fn get_quantity(arg: &ArgMatches) -> Result { - u16::from_str(arg.value_of("quantity").unwrap()) -} - -fn get_period_ms(value: &str) -> Result { - let num = usize::from_str(value)?; - Ok(Duration::from_millis(num as u64)) -} - -fn get_address_range(arg: &ArgMatches) -> Result { - Ok(AddressRange::try_from(get_start(arg)?, get_quantity(arg)?)?) -} - -fn get_indexed_register_value(arg: &ArgMatches) -> Result, Error> { - Ok(Indexed::new(get_index(arg)?, get_value(arg)?)) -} - -fn get_command(matches: &ArgMatches) -> Result { - if let Some(matches) = matches.subcommand_matches("rc") { - return Ok(Command::ReadCoils(get_address_range(matches)?)); - } - - if let Some(matches) = matches.subcommand_matches("rdi") { - return Ok(Command::ReadDiscreteInputs(get_address_range(matches)?)); - } - - if let Some(matches) = matches.subcommand_matches("rhr") { - return Ok(Command::ReadHoldingRegisters(get_address_range(matches)?)); - } - - if let Some(matches) = matches.subcommand_matches("rir") { - return Ok(Command::ReadInputRegisters(get_address_range(matches)?)); - } - - if let Some(matches) = matches.subcommand_matches("wsr") { - return Ok(Command::WriteSingleRegister(get_indexed_register_value( - matches, - )?)); - } - - if let Some(matches) = matches.subcommand_matches("wsc") { - let index = get_index(matches)?; - let value = bool::from_str(matches.value_of("value").unwrap())?; - return Ok(Command::WriteSingleCoil(Indexed::new(index, value))); - } - - if let Some(matches) = matches.subcommand_matches("wmc") { - let start = get_start(matches)?; - let values = get_bit_values(matches)?; - return Ok(Command::WriteMultipleCoils(WriteMultiple::from( - start, values, - )?)); - } - - if let Some(matches) = matches.subcommand_matches("wmr") { - let start = get_start(matches)?; - let values = get_register_values(matches)?; - return Ok(Command::WriteMultipleRegisters(WriteMultiple::from( - start, values, - )?)); - } - - Err(Error::MissingSubCommand) -} - -fn parse_args() -> Result { - let matches = App::new("Modbus Client Console") - .version("0.1.0") - .about("Simple program to show off client API") - .arg( - Arg::with_name("host") - .short("h") - .long("host") - .takes_value(true) - .required(false) - .default_value("127.0.0.1:502") - .help("A socket address"), - ) - .arg( - Arg::with_name("id") - .short("i") - .long("id") - .takes_value(true) - .required(false) - .default_value("1") - .help("The unit id of Modbus server"), - ) - .arg( - Arg::with_name("period") - .short("p") - .long("period") - .takes_value(true) - .required(false) - .help("Optional polling period in milliseconds"), - ) - .subcommand( - SubCommand::with_name("rc") - .about("read coils") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address"), - ) - .arg( - Arg::with_name("quantity") - .short("q") - .long("quantity") - .required(true) - .takes_value(true) - .help("quantity of values"), - ), - ) - .subcommand( - SubCommand::with_name("rdi") - .about("read discrete inputs") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address"), - ) - .arg( - Arg::with_name("quantity") - .short("q") - .long("quantity") - .required(true) - .takes_value(true) - .help("quantity of values"), - ), - ) - .subcommand( - SubCommand::with_name("rhr") - .about("read holding registers") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address"), - ) - .arg( - Arg::with_name("quantity") - .short("q") - .long("quantity") - .required(true) - .takes_value(true) - .help("quantity of values"), - ), - ) - .subcommand( - SubCommand::with_name("rir") - .about("read input registers") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address"), - ) - .arg( - Arg::with_name("quantity") - .short("q") - .long("quantity") - .required(true) - .takes_value(true) - .help("quantity of values"), - ), - ) - .subcommand( - SubCommand::with_name("wsc") - .about("write single coil") - .arg( - Arg::with_name("index") - .short("i") - .long("index") - .required(true) - .takes_value(true) - .help("the address of the coil"), - ) - .arg( - Arg::with_name("value") - .short("v") - .long("value") - .required(true) - .takes_value(true) - .help("the value of the coil (ON or OFF)"), - ), - ) - .subcommand( - SubCommand::with_name("wsr") - .about("write single register") - .arg( - Arg::with_name("index") - .short("i") - .long("index") - .required(true) - .takes_value(true) - .help("the address of the register"), - ) - .arg( - Arg::with_name("value") - .short("v") - .long("value") - .required(true) - .takes_value(true) - .help("the value of the register"), - ), - ) - .subcommand( - SubCommand::with_name("wmc") - .about("write multiple coils") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address of the coils"), - ) - .arg( - Arg::with_name("values") - .short("v") - .long("values") - .required(true) - .takes_value(true) - .help("the values of the coils specified as a string of 1 and 0 (e.g. 10100011)"), - ), - ) - .subcommand( - SubCommand::with_name("wmr") - .about("write multiple registers") - .arg( - Arg::with_name("start") - .short("s") - .long("start") - .required(true) - .takes_value(true) - .help("the starting address of the registers"), - ) - .arg( - Arg::with_name("values") - .short("v") - .long("values") - .required(true) - .takes_value(true) - .help("the values of the registers specified as a comma delimited list (e.g. 1,4,7)"), - ), - ) - .get_matches(); - - let address = SocketAddr::from_str(matches.value_of("host").unwrap())?; - let id = UnitId::new(u8::from_str(matches.value_of("id").unwrap())?); - let period = match matches.value_of("period") { - Some(s) => Some(get_period_ms(s)?), - None => None, - }; - let command = get_command(&matches)?; - - Ok(Args::new(address, id, command, period)) -} - -impl std::error::Error for Error {} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { - match self { - Error::BadRange(err) => write!(f, "{err}"), - Error::BadAddr(err) => write!(f, "{err}"), - Error::BadInt(err) => err.fmt(f), - Error::BadBool(err) => err.fmt(f), - Error::BadCharInBitString(char) => write!(f, "Bad character in bit string: {char}"), - Error::Request(err) => err.fmt(f), - Error::MissingSubCommand => f.write_str("No sub-command provided"), - Error::Shutdown => f.write_str("channel was shut down"), - } - } -} - impl From for Error { fn from(err: rodbus::RequestError) -> Self { Error::Request(err) @@ -530,3 +480,9 @@ impl From for Error { Self::Shutdown } } + +impl From<&str> for Error { + fn from(msg: &str) -> Self { + Self::UnableToConnect(msg.to_string()) + } +} diff --git a/rodbus/src/common/bits.rs b/rodbus/src/common/bits.rs index d6d2845b..8c3e69d1 100644 --- a/rodbus/src/common/bits.rs +++ b/rodbus/src/common/bits.rs @@ -1,5 +1,5 @@ pub(crate) fn num_bytes_for_bits(count: u16) -> usize { - (count as usize + 7) / 8 + (count as usize).div_ceil(8) } #[cfg(test)] diff --git a/rodbus/tests/integration_test.rs b/rodbus/tests/integration_test.rs index 54c1de3f..5ee6af1e 100644 --- a/rodbus/tests/integration_test.rs +++ b/rodbus/tests/integration_test.rs @@ -1,3 +1,4 @@ +//! integration test use std::net::SocketAddr; use std::str::FromStr; use std::time::Duration;