diff --git a/.cargo/audit.toml b/.cargo/audit.toml index 08346a0e..c6c46b76 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -28,5 +28,23 @@ ignore = [ "RUSTSEC-2026-0098", # rustls-webpki: URI name constraints "RUSTSEC-2026-0099", # rustls-webpki: name constraints vs wildcard names "RUSTSEC-2026-0104", # rustls-webpki: panic in CRL parsing - "RUSTSEC-2025-0134", # rustls-pemfile unmaintained (transitive via rumqttc) + "RUSTSEC-2025-0134", # rustls-pemfile unmaintained (transitive via rumqttc and zenoh-link-commons) + + # lz4_flex 0.10.0, a required dependency of zenoh-transport 1.10.1 (the + # latest zenoh). zenoh pins `lz4_flex = "0.10.0"`; the fixed versions are + # 0.11.6+ and 0.12.1+, out of semver range, so no in-range upgrade or + # `[patch]` exists. + # + # Not reachable through aimdb-zenoh-connector. The advisory is about + # decompression; zenoh-transport decompresses only in + # `WBatch::decompress`, behind `#[cfg(feature = "transport_compression")]`. + # The connector depends on zenoh without default features and never enables + # compression; `make test-embedded` asserts that. Its other lz4_flex calls + # only size buffers (`get_maximum_output_size`). + # + # Tracked upstream: eclipse-zenoh/zenoh#2589, bump in #2499. Drop this when + # a zenoh release takes it. + "RUSTSEC-2026-0041", # lz4_flex: uninitialized memory in decompression + "RUSTSEC-2024-0436", # paste unmaintained (via zenoh-keyexpr/token-cell) + "RUSTSEC-2024-0449", # unsafe-libyaml unmaintained (via serde_yaml from zenoh-config; the connector builds Config in code, never from YAML) ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4349083..541574d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,6 +162,27 @@ jobs: cargo +nightly miri test -p aimdb-embassy-adapter \ --no-default-features --features "alloc,embassy-sync,embassy-time" + # ros2:// against real ROS 2 distributions: rmw_zenohd and the ros2 CLI + ros2-interop: + name: ROS 2 interop (${{ matrix.distro }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + distro: [jazzy, lyrical] + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v2 + with: + rustflags: "" + + - name: Interop with ROS 2 ${{ matrix.distro }} + run: make ros2-interop DISTRO=${{ matrix.distro }} + # Comprehensive validation using Makefile comprehensive-check: name: Comprehensive Development Check diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index ecedb550..ae3848eb 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -55,3 +55,7 @@ jobs: - name: Run cargo-deny run: cargo deny check + + # `cargo deny check` sees default features only, which leave `zenoh` out. + - name: Run cargo-deny on the Zenoh connector's std graph + run: cargo deny --features "std,transport-tls,transport-quic,transport-ws,auth-usrpwd" --manifest-path aimdb-zenoh-connector/Cargo.toml check diff --git a/CHANGELOG.md b/CHANGELOG.md index 04bdce37..8ee531d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > - [aimdb-codegen/CHANGELOG.md](aimdb-codegen/CHANGELOG.md) > - [aimdb-data-contracts/CHANGELOG.md](aimdb-data-contracts/CHANGELOG.md) > - [aimdb-derive/CHANGELOG.md](aimdb-derive/CHANGELOG.md) +> - [aimdb-cdr/CHANGELOG.md](aimdb-cdr/CHANGELOG.md) > - [aimdb-tokio-adapter/CHANGELOG.md](aimdb-tokio-adapter/CHANGELOG.md) > - [aimdb-embassy-adapter/CHANGELOG.md](aimdb-embassy-adapter/CHANGELOG.md) > - [aimdb-mqtt-connector/CHANGELOG.md](aimdb-mqtt-connector/CHANGELOG.md) +> - [aimdb-zenoh-connector/CHANGELOG.md](aimdb-zenoh-connector/CHANGELOG.md) > - [aimdb-knx-connector/CHANGELOG.md](aimdb-knx-connector/CHANGELOG.md) > - [aimdb-websocket-connector/CHANGELOG.md](aimdb-websocket-connector/CHANGELOG.md) > - [aimdb-uds-connector/CHANGELOG.md](aimdb-uds-connector/CHANGELOG.md) @@ -29,6 +31,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added — Zenoh connector and ROS 2 topics + +- **AimDB records as ROS 2 topics, with no ROS install on the AimDB side.** + `Ros2Connector` speaks rmw_zenoh's conventions (data keys, liveliness + tokens, attachments, CDR), so `ros2 node list`, `ros2 topic info -v`, + `ros2 topic echo` and `ros2 topic pub` see AimDB as a ROS node. A struct + becomes a ROS message with `#[derive(RosMessage)]`. + ([aimdb-zenoh-connector](aimdb-zenoh-connector/CHANGELOG.md), + [aimdb-data-contracts](aimdb-data-contracts/CHANGELOG.md), + [aimdb-derive](aimdb-derive/CHANGELOG.md)) +- **`zenoh://` links** with Zenoh key expressions, captures and keys, and a + gateway that bridges devices on plain Zenoh to ROS 2 on one router + connection. ([aimdb-zenoh-connector](aimdb-zenoh-connector/CHANGELOG.md)) +- **`aimdb-cdr`**: `no_std` serde for OMG CDR, the ROS 2 wire format. + ([aimdb-cdr](aimdb-cdr/CHANGELOG.md)) +- **Connectors learn each link's record type and wire format**: + `RouteInfo::type_id`, `InboundDispatch::routes()` and the reserved + `aimdb.wire_format` link key. ([aimdb-core](aimdb-core/CHANGELOG.md)) + ### Added — wildcard inbound links - **One inbound link can feed many topics into one record.** diff --git a/Cargo.lock b/Cargo.lock index b775a6e2..d5c7e307 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aead" version = "0.5.2" @@ -44,6 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -79,6 +86,14 @@ dependencies = [ "tokio", ] +[[package]] +name = "aimdb-cdr" +version = "0.1.0" +dependencies = [ + "hiroz-cdr", + "serde", +] + [[package]] name = "aimdb-cli" version = "0.7.0" @@ -128,7 +143,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.108", + "syn 2.0.119", "toml 0.8.23", ] @@ -149,7 +164,7 @@ dependencies = [ "portable-atomic", "serde", "serde_json", - "spin", + "spin 0.9.9", "thiserror 2.0.17", "tokio", "tracing", @@ -159,6 +174,7 @@ dependencies = [ name = "aimdb-data-contracts" version = "0.2.0" dependencies = [ + "aimdb-cdr", "aimdb-core", "aimdb-derive", "futures", @@ -175,7 +191,7 @@ version = "0.2.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -276,7 +292,7 @@ dependencies = [ "futures", "heapless 0.8.0", "rand 0.8.6", - "rcgen", + "rcgen 0.13.2", "rumqttc", "rustls-native-certs", "serde", @@ -426,6 +442,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "aimdb-zenoh-connector" +version = "0.1.0" +dependencies = [ + "aimdb-core", + "aimdb-data-contracts", + "aimdb-tokio-adapter", + "serde", + "tokio", + "trybuild", + "twox-hash 2.1.5", + "zenoh", + "zenoh-keyexpr", +] + [[package]] name = "aligned" version = "0.4.3" @@ -435,6 +466,12 @@ dependencies = [ "as-slice", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -506,6 +543,21 @@ version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + [[package]] name = "as-slice" version = "0.2.1" @@ -515,6 +567,45 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "asn1-rs" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 2.0.17", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "async-channel" version = "2.5.0" @@ -546,7 +637,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -656,7 +747,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" dependencies = [ - "rustc_version", + "rustc_version 0.2.3", ] [[package]] @@ -677,6 +768,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -692,6 +789,15 @@ dependencies = [ "const-init", ] +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +dependencies = [ + "serde", +] + [[package]] name = "bit_field" version = "0.10.3" @@ -715,6 +821,9 @@ name = "bitflags" version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +dependencies = [ + "serde_core", +] [[package]] name = "block-buffer" @@ -734,6 +843,15 @@ dependencies = [ "aligned", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.19.0" @@ -746,6 +864,26 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -808,6 +946,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link 0.2.1", ] @@ -880,7 +1019,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -932,6 +1071,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -965,6 +1114,27 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "cordyceps" version = "0.3.4" @@ -1031,7 +1201,7 @@ checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1052,6 +1222,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.5.1" @@ -1064,7 +1243,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -1083,7 +1262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1092,6 +1271,56 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "crossbeam" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71406cd8807725f7ac2f999a4cdd32e98f829fdf65f528343cebf945e41df1e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1141,8 +1370,18 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -1156,7 +1395,20 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.108", + "syn 2.0.119", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.119", ] [[package]] @@ -1165,9 +1417,20 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core", + "darling_core 0.20.11", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1218,7 +1481,7 @@ dependencies = [ "defmt-parser", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1262,6 +1525,20 @@ dependencies = [ "time", ] +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "der_derive" version = "0.8.0" @@ -1270,7 +1547,7 @@ checksum = "59600e2c2d636fde9b65e99cc6445ac770c63d3628195ff39932b8d6d7409903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1278,6 +1555,9 @@ name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] [[package]] name = "digest" @@ -1291,6 +1571,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1299,7 +1600,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1317,6 +1618,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1416,10 +1723,10 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" dependencies = [ - "darling", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -1899,6 +2206,7 @@ version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ + "parking", "pin-project-lite", ] @@ -1924,6 +2232,18 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "fastbloom" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef975e30683b2d965054bb0a836f8973857c4ebf6acf274fe46617cd285060d8" +dependencies = [ + "foldhash 0.2.0", + "libm", + "portable-atomic", + "siphasher", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1952,6 +2272,17 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flate2" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +dependencies = [ + "crc32fast", + "miniz_oxide", + "zlib-rs", +] + [[package]] name = "flume" version = "0.11.1" @@ -1960,7 +2291,8 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", - "spin", + "nanorand", + "spin 0.9.9", ] [[package]] @@ -1975,6 +2307,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2071,7 +2409,7 @@ checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -2135,8 +2473,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -2158,11 +2498,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.0", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -2175,6 +2517,26 @@ dependencies = [ "polyval", ] +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "glob" version = "0.3.3" @@ -2204,7 +2566,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -2231,6 +2593,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -2238,6 +2606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", + "allocator-api2", ] [[package]] @@ -2246,7 +2615,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -2254,6 +2623,11 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -2353,13 +2727,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] -name = "hkdf" -version = "0.12.4" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hiroz-cdr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69398421bf7e64822904d8a4744186af65c56fce141756965c86ad27565c2e43" +dependencies = [ + "bytemuck", + "byteorder", + "serde", + "thiserror 2.0.17", + "zenoh-buffers", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] [[package]] name = "hmac" @@ -2370,6 +2763,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "http" version = "1.4.0" @@ -2415,6 +2817,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" + [[package]] name = "hyper" version = "1.8.1" @@ -2486,7 +2894,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", "system-configuration", "tokio", "tower-service", @@ -2632,6 +3040,17 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.12.0" @@ -2669,6 +3088,15 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + [[package]] name = "iri-string" version = "0.7.12" @@ -2705,12 +3133,124 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jiff" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" +dependencies = [ + "defmt 1.1.1", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link 0.2.1", +] + +[[package]] +name = "jiff-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +dependencies = [ + "defmt 1.1.1", + "log", +] + +[[package]] +name = "jiff-static" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8377070c6bae868759445e5a77f66d84f0b72f3a054bfb00e6d038b8282da7" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.17", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version 0.4.1", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + [[package]] name = "jobserver" version = "0.1.35" @@ -2732,6 +3272,35 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures 0.2.17", +] + +[[package]] +name = "keyed-set" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d255a6b6ecd77bb93ce91de984d7039bff7503f500eb4851a1269732f22baf" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "knx-connector-demo-common" version = "0.1.0" @@ -2742,13 +3311,28 @@ dependencies = [ "serde", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin", + "spin 0.9.9", ] [[package]] @@ -2763,12 +3347,31 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +[[package]] +name = "libredox" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "libc", +] + [[package]] name = "libsqlite3-sys" version = "0.30.1" @@ -2832,6 +3435,21 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" + +[[package]] +name = "lz4_flex" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8c72594ac26bfd34f2d99dfced2edfaddfe8a476e3ff2ca0eb293d925c4f83" +dependencies = [ + "twox-hash 1.6.3", +] + [[package]] name = "mach2" version = "0.4.3" @@ -2890,6 +3508,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.1.0" @@ -2926,6 +3560,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.16", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -2981,6 +3624,31 @@ dependencies = [ "libc", ] +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonempty-collections" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e216d0e8cf9d54fa66e5780f6e1d5dc96d1c1b3c25aeba3b6758548bcbbd8b9d" +dependencies = [ + "serde", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2990,6 +3658,16 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint-dig" version = "0.8.6" @@ -3041,6 +3719,25 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -3087,7 +3784,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -3114,6 +3811,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "p256" version = "0.13.2" @@ -3159,6 +3862,12 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -3182,6 +3891,12 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pem" version = "3.0.6" @@ -3192,6 +3907,16 @@ dependencies = [ "serde_core", ] +[[package]] +name = "pem" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d354a98a3d1251555de99e8fdd8afda05573c31b82f59063a7b0a29b5527f120" +dependencies = [ + "base64 0.23.1", + "serde_core", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -3199,26 +3924,123 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "pest" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "45d3aca230fad2e6f6317ca0a72724338c4960cb97168a85cdee66df4a9a21a8" +dependencies = [ + "memchr", + "ucd-trie", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "pest_derive" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "284b60557f2c4a2e72ad3f2d34d42685a2fa4a6a61d0d2a10c0ae2a5e916c2cf" +dependencies = [ + "pest", + "pest_generator", +] [[package]] -name = "pkcs1" -version = "0.7.5" +name = "pest_generator" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +checksum = "1d9d1f08a115309ee99268cf85e5228e0e56aa9caf8841ec12866b6be07c3109" dependencies = [ - "der 0.7.10", - "pkcs8", - "spki", + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pest_meta" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed93ba1a9ffcca32130a5188701c81c0c49cf00d4b7c5007d5148951d743adcb" +dependencies = [ + "pest", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap 2.12.0", + "serde", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8", + "spki", ] [[package]] @@ -3237,6 +4059,38 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "pnet_base" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc190d4067df16af3aba49b3b74c469e611cad6314676eaf1157f31aa0fb2f7" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_datalink" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79e70ec0be163102a332e1d2d5586d362ad76b01cec86f830241f2b6452a7b7" +dependencies = [ + "ipnetwork", + "libc", + "pnet_base", + "pnet_sys", + "winapi", +] + +[[package]] +name = "pnet_sys" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d4643d3d4db6b08741050c2f3afa9a892c4244c085a72fcda93c9c2c9a00f4b" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "polyval" version = "0.6.2" @@ -3251,13 +4105,22 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" dependencies = [ "critical-section", ] +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + [[package]] name = "postcard" version = "1.1.3" @@ -3301,7 +4164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -3313,6 +4176,15 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.6+spec-1.1.0", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -3332,7 +4204,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -3344,6 +4216,64 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.6.1", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe" +dependencies = [ + "bytes", + "fastbloom", + "getrandom 0.4.2", + "lru-slab", + "rand 0.10.1", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af66907df18639dcf4db56ca65490cabc4b27a97dbadd96f2926cca73298f016" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.1", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" version = "1.0.47" @@ -3441,17 +4371,40 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.0", +] + [[package]] name = "rcgen" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" dependencies = [ - "pem", + "pem 3.0.6", + "ring", + "rustls-pki-types", + "time", + "yasna 0.5.2", +] + +[[package]] +name = "rcgen" +version = "0.14.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8774e05a7d0de114588e6a28fe7e71694b82614ed569d86d8b389dfbc98b8ad8" +dependencies = [ + "pem 4.0.0", "ring", "rustls-pki-types", "time", - "yasna", + "x509-parser", + "yasna 0.6.0", ] [[package]] @@ -3472,6 +4425,36 @@ dependencies = [ "bitflags 2.13.1", ] +[[package]] +name = "redox_users" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" +dependencies = [ + "libredox", + "thiserror 2.0.17", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "regex" version = "1.13.1" @@ -3582,6 +4565,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ringbuffer-spsc" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3e7aa0a681b232e7cd7f856a53b10603df88ca74b79a8d8088845185492e35" +dependencies = [ + "array-init", + "crossbeam", +] + [[package]] name = "rlsf" version = "0.2.1" @@ -3594,6 +4587,20 @@ dependencies = [ "svgbobdoc", ] +[[package]] +name = "ron" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" +dependencies = [ + "bitflags 2.13.1", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + [[package]] name = "rsa" version = "0.9.10" @@ -3652,6 +4659,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + [[package]] name = "rustc_version" version = "0.2.3" @@ -3661,6 +4674,24 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "1.1.2" @@ -3683,6 +4714,7 @@ dependencies = [ "aws-lc-rs", "log", "once_cell", + "ring", "rustls-pki-types", "rustls-webpki 0.103.15", "subtle", @@ -3716,9 +4748,37 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.15", + "security-framework 3.7.0", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f" + [[package]] name = "rustls-webpki" version = "0.102.8" @@ -3772,6 +4832,44 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "either", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 3.0.3", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3803,6 +4901,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + [[package]] name = "security-framework" version = "2.11.1" @@ -3898,11 +5006,22 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] -name = "serde_json" +name = "serde_derive_internals" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" @@ -3955,13 +5074,46 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" +dependencies = [ + "base64 0.22.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.12.0", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap", + "indexmap 2.12.0", "itoa", "ryu", "serde", @@ -4008,6 +5160,22 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4017,6 +5185,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shellexpand" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" +dependencies = [ + "dirs", +] + [[package]] name = "shlex" version = "2.0.1" @@ -4042,6 +5219,34 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version 0.4.1", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" + [[package]] name = "slab" version = "0.4.11" @@ -4068,6 +5273,16 @@ dependencies = [ "managed", ] +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "socket2" version = "0.6.1" @@ -4087,6 +5302,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spin" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" + [[package]] name = "spki" version = "0.7.3" @@ -4097,6 +5318,40 @@ dependencies = [ "der 0.7.10", ] +[[package]] +name = "stabby" +version = "72.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d53d2428934c46277fafd2d41e39357595aa1e47954c75db2b14ed90632f3cc" +dependencies = [ + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "72.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f375eae680bb54203ee5e47d4cd2ae7b79c0a79ed90919279f38f500ad53f190" +dependencies = [ + "rustc_version 0.4.1", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "72.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea664671a576c5f7e32fee291ac123d82af5e92b0689beb3555347c00c76eef1" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -4185,9 +5440,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.108" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -4235,7 +5490,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4280,7 +5535,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4346,7 +5601,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4357,7 +5612,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4380,6 +5635,7 @@ dependencies = [ "powerfmt", "serde_core", "time-core", + "time-macros", ] [[package]] @@ -4388,6 +5644,16 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" +[[package]] +name = "time-macros" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.2" @@ -4408,6 +5674,36 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tinyvec" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" + +[[package]] +name = "tls-listener" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1461056cc1ef47003f7ee16e4cef3741068d4c7f6b627bfce49b7c00c120a530" +dependencies = [ + "futures-util", + "pin-project-lite", + "thiserror 2.0.17", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "token-cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb48920ae769b58126c8c93269805011c793201f95fde28b479b81a9a531bbde" +dependencies = [ + "paste", + "portable-atomic", + "rustversion", +] + [[package]] name = "tokio" version = "1.48.0" @@ -4420,7 +5716,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", ] @@ -4449,7 +5745,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4526,6 +5822,18 @@ dependencies = [ "tokio-stream", ] +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.24.0", +] + [[package]] name = "tokio-tungstenite" version = "0.26.2" @@ -4559,6 +5867,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", "pin-project-lite", "tokio", ] @@ -4572,7 +5881,7 @@ dependencies = [ "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", - "toml_edit", + "toml_edit 0.22.27", ] [[package]] @@ -4581,7 +5890,7 @@ version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" dependencies = [ - "indexmap", + "indexmap 2.12.0", "serde_core", "serde_spanned 1.1.1", "toml_datetime 1.1.1+spec-1.1.0", @@ -4614,7 +5923,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap", + "indexmap 2.12.0", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -4622,6 +5931,18 @@ dependencies = [ "winnow 0.7.14", ] +[[package]] +name = "toml_edit" +version = "0.25.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0db3bae107c9522f86d361697dee1d7386a2ddcf659d5aea5159819a21a3c4a7" +dependencies = [ + "indexmap 2.12.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.3", +] + [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" @@ -4709,7 +6030,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4733,6 +6054,16 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.20" @@ -4743,12 +6074,15 @@ dependencies = [ "nu-ansi-term", "once_cell", "regex-automata", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] @@ -4769,7 +6103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -4804,6 +6138,24 @@ dependencies = [ "toml 1.1.0+spec-1.1.0", ] +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.6", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + [[package]] name = "tungstenite" version = "0.26.2" @@ -4838,12 +6190,54 @@ dependencies = [ "utf-8", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "twox-hash" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86a801b3cea342a06d468c8710662aa29e5e05e4f5c0d62f00bbb7f2ad7941c2" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uhlc" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62a645e3e4e6c85b7abe49b086aa3204119431f42b6123b0070419fb6e9d24e" +dependencies = [ + "humantime", + "lazy_static", + "log", + "rand 0.8.6", + "serde", + "spin 0.10.1", +] + [[package]] name = "unescaper" version = "0.1.8" @@ -4899,6 +6293,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unzip-n" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5bb2756c16fb66f80cfbf5fb0e0c09a7001e739f453c9ec241b9c8b1556fda" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "url" version = "2.5.7" @@ -4940,6 +6345,30 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "validated_struct" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869a93e8a7286e339e1128630051d82babbcd75d585975af07b9f3327220e60e" +dependencies = [ + "json5", + "serde", + "serde_json", + "validated_struct_macros", +] + +[[package]] +name = "validated_struct_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c44ce98e7227a04eeb4cf9c784109a5c9710e54849ceb4f09f8597247897f1e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "unzip-n", +] + [[package]] name = "valuable" version = "0.1.1" @@ -4958,6 +6387,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.5" @@ -5064,7 +6499,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", "wasm-bindgen-shared", ] @@ -5107,7 +6542,7 @@ checksum = "94eb68555b95bcea5e8cf4abe280b529049479fa995bfc23734af96a6aedc120" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -5133,7 +6568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap", + "indexmap 2.12.0", "wasm-encoder", "wasmparser", ] @@ -5146,7 +6581,7 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.13.1", "hashbrown 0.15.5", - "indexmap", + "indexmap 2.12.0", "semver 1.0.28", ] @@ -5251,6 +6686,34 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -5336,7 +6799,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -5347,7 +6810,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -5598,6 +7061,9 @@ name = "winnow" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] [[package]] name = "wit-bindgen" @@ -5633,9 +7099,9 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap", + "indexmap 2.12.0", "prettyplease", - "syn 2.0.108", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -5651,7 +7117,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -5664,7 +7130,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.13.1", - "indexmap", + "indexmap 2.12.0", "log", "serde", "serde_derive", @@ -5683,7 +7149,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap", + "indexmap 2.12.0", "log", "semver 1.0.28", "serde", @@ -5699,6 +7165,24 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "x509-parser" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 2.0.17", + "time", +] + [[package]] name = "yasna" version = "0.5.2" @@ -5709,8 +7193,18 @@ dependencies = [ ] [[package]] -name = "yoke" -version = "0.8.1" +name = "yasna" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5f6765e852b9b4dc8e2a76843e4d64d1cea8e79bcde0b6901aea8e7c7f08282" +dependencies = [ + "bit-vec", + "time", +] + +[[package]] +name = "yoke" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ @@ -5727,10 +7221,499 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", "synstructure", ] +[[package]] +name = "zenoh" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ba5d28a1197653aae4bb024fd74a9d5c7051d5a19a77f3a43d83f40c22584" +dependencies = [ + "ahash", + "arc-swap", + "async-trait", + "bytes", + "const_format", + "flate2", + "flume", + "futures", + "git-version", + "itertools 0.14.0", + "json5", + "lazy_static", + "nonempty-collections", + "once_cell", + "petgraph", + "phf", + "rand 0.8.6", + "rustc_version 0.4.1", + "serde", + "serde_json", + "socket2 0.5.10", + "tokio", + "tokio-util", + "tracing", + "uhlc", + "vec_map", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-keyexpr", + "zenoh-link", + "zenoh-link-commons", + "zenoh-macros", + "zenoh-plugin-trait", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-sync", + "zenoh-task", + "zenoh-transport", + "zenoh-util", +] + +[[package]] +name = "zenoh-buffers" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555a8169c9888fc5571f1b38d2843a63db786621e153abad1b075c40b20e83b4" +dependencies = [ + "zenoh-collections", +] + +[[package]] +name = "zenoh-codec" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc959f727893eab9b66ec051c8f4a2d6f66b4ee70bf23f2ed244aa754705e854" +dependencies = [ + "rand 0.8.6", + "tracing", + "uhlc", + "zenoh-buffers", + "zenoh-protocol", +] + +[[package]] +name = "zenoh-collections" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c05abd8dcfd2239a8dfb5b79bd4ed85094c6bb6d6b991d3529bff364cc48e29" +dependencies = [ + "ahash", +] + +[[package]] +name = "zenoh-config" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59799d556b4fac79886cb0a9c90f3bc48d0894816b99c8a90a3509b1809a02dd" +dependencies = [ + "json5", + "nonempty-collections", + "num_cpus", + "secrecy", + "serde", + "serde_json", + "serde_with", + "serde_yaml", + "tracing", + "uhlc", + "validated_struct", + "zenoh-core", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-protocol", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975073c51353c1c33e81a98370bf3560863540913e5f30091923f5a328fc46d4" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-result", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-crypto" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281a36cfd351ba9232a24899d946a782d0ff3ac0c3d759f87f3e7cbe09a4553" +dependencies = [ + "aes", + "hmac", + "rand 0.8.6", + "rand_chacha 0.3.1", + "sha3", + "zenoh-result", +] + +[[package]] +name = "zenoh-keyexpr" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c6fcb7f18846b4e9b097c61ed7c656ec8d7858ab54a12d5f5025fe1514caae" +dependencies = [ + "getrandom 0.2.16", + "hashbrown 0.16.0", + "keyed-set", + "rand 0.8.6", + "schemars 1.2.2", + "serde", + "token-cell", + "zenoh-result", +] + +[[package]] +name = "zenoh-link" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55c4fbc923328f0b62b1b492723ff53b757a36421f70218e652f0aa899cde6c" +dependencies = [ + "zenoh-config", + "zenoh-link-commons", + "zenoh-link-quic", + "zenoh-link-tcp", + "zenoh-link-tls", + "zenoh-link-udp", + "zenoh-link-ws", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-commons" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d52520b4c22d05173c8621e3cbe18d838a17d74477891ed9c59a7aeedaa325d" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "flume", + "futures", + "quinn", + "quinn-proto", + "rcgen 0.14.10", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "rustls-webpki 0.103.15", + "secrecy", + "serde", + "socket2 0.5.10", + "time", + "tokio", + "tokio-util", + "tracing", + "webpki-roots", + "x509-parser", + "zenoh-buffers", + "zenoh-codec", + "zenoh-config", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-util", +] + +[[package]] +name = "zenoh-link-quic" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9fecc8832bb943631f75d7c4e4839a414d7bebbe80c0f695f14b2cd8c84759" +dependencies = [ + "async-trait", + "rustls-webpki 0.103.15", + "time", + "tracing", + "zenoh-core", + "zenoh-link-commons", + "zenoh-link-quic_datagram", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-quic_datagram" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1af3abf41c719c82ca356864b5ddeeb7c77cb29fe777776b40b31eb4d19de288" +dependencies = [ + "async-trait", + "rustls-webpki 0.103.15", + "time", + "tokio-util", + "tracing", + "zenoh-core", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-tcp" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4702d55fe9f17cbd1d3b601901f8ba0a693a7ad1ce685a1ea4c60f775552b7" +dependencies = [ + "async-trait", + "socket2 0.5.10", + "tokio", + "tokio-util", + "tracing", + "zenoh-config", + "zenoh-core", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-tls" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce65fd71b4631821a85058542e28faac0151af6c53cd61f2dfafc7e16c4d6c4" +dependencies = [ + "async-trait", + "base64 0.22.1", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "rustls-webpki 0.103.15", + "secrecy", + "socket2 0.5.10", + "time", + "tls-listener", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "webpki-roots", + "x509-parser", + "zenoh-config", + "zenoh-core", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-link-udp" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b140e7b65715fe8b29b706b2b9fc3009fc6181346931c8926d290113fe38df4b" +dependencies = [ + "async-trait", + "libc", + "socket2 0.5.10", + "tokio", + "tokio-util", + "tracing", + "windows-sys 0.61.2", + "zenoh-buffers", + "zenoh-core", + "zenoh-link-commons", + "zenoh-link-quic_datagram", + "zenoh-protocol", + "zenoh-result", + "zenoh-sync", + "zenoh-util", +] + +[[package]] +name = "zenoh-link-ws" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e317201b8e0da26395e21c68dfe45197eca8ffddd32a3ba5a15f8ef24514069" +dependencies = [ + "async-trait", + "futures-util", + "tokio", + "tokio-tungstenite 0.24.0", + "tokio-util", + "tracing", + "url", + "zenoh-core", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-util", +] + +[[package]] +name = "zenoh-macros" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f483b343fd79b6c1bd7d79f130b5c6c208e7fef243a4d7966a6bf9fdecbd70f8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "zenoh-keyexpr", +] + +[[package]] +name = "zenoh-plugin-trait" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d57f491f63afa7413d68ee68e4de2bc9ce361c4ac89a76d5a0a0e3ca0624e21" +dependencies = [ + "git-version", + "libloading", + "serde", + "stabby", + "tracing", + "zenoh-config", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-protocol" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4492192986df044627f33c8eeb8aa237fb4d3bbd2d8cc68bc7eee16748c2fb61" +dependencies = [ + "const_format", + "rand 0.8.6", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-result", +] + +[[package]] +name = "zenoh-result" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6d0ca24186d9cfbf14f2d08b8b0a09afac690fe5cd68899d8f896f9247a3dd" +dependencies = [ + "anyhow", +] + +[[package]] +name = "zenoh-runtime" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e8ea6ed9fb3300d02bc303b3202a21a758aa5d7a1e7dcc38610428910af9f9" +dependencies = [ + "lazy_static", + "ron", + "serde", + "tokio", + "tracing", + "zenoh-macros", + "zenoh-result", +] + +[[package]] +name = "zenoh-sync" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d57ed2156b61df6e877b03fb13dd72227d3d286a7fa689120109bad289ddf12b" +dependencies = [ + "arc-swap", + "event-listener", + "futures", + "tokio", + "zenoh-buffers", + "zenoh-collections", + "zenoh-core", +] + +[[package]] +name = "zenoh-task" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887115c0f81c72ff8c9b99e6fccd9e1c3829d83e16b8b063174786b9fba08810" +dependencies = [ + "futures", + "tokio", + "tokio-util", + "tracing", + "zenoh-core", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-transport" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72bae2e0aca56ac6431bd6c37c6ac3fcc9367446cbb356bd44137cc01d1493ee" +dependencies = [ + "async-trait", + "crossbeam-utils", + "flume", + "futures", + "lazy_static", + "lz4_flex", + "rand 0.8.6", + "ringbuffer-spsc", + "serde", + "sha3", + "tokio", + "tokio-util", + "tracing", + "zenoh-buffers", + "zenoh-codec", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-link", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-sync", + "zenoh-task", + "zenoh-util", +] + +[[package]] +name = "zenoh-util" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a473dcc62026b9d9589acc22c62b04cb7dab4070bba5543d2afac741ddf947" +dependencies = [ + "async-trait", + "const_format", + "flume", + "home", + "humantime", + "lazy_static", + "libc", + "libloading", + "pnet_datalink", + "schemars 1.2.2", + "serde", + "serde_json", + "shellexpand", + "tokio", + "tracing", + "tracing-subscriber", + "winapi", + "zenoh-core", + "zenoh-result", +] + [[package]] name = "zerocopy" version = "0.8.27" @@ -5748,7 +7731,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] [[package]] @@ -5768,7 +7751,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", "synstructure", ] @@ -5808,5 +7791,11 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.119", ] + +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" diff --git a/Cargo.toml b/Cargo.toml index 34ffbd3f..a102801e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "aimdb-derive", + "aimdb-cdr", "aimdb-data-contracts", "aimdb-core", "aimdb-client", @@ -11,6 +12,7 @@ members = [ "aimdb-persistence", "aimdb-persistence-sqlite", "aimdb-mqtt-connector", + "aimdb-zenoh-connector", "aimdb-knx-connector", "aimdb-websocket-connector", "aimdb-uds-connector", diff --git a/Makefile b/Makefile index dc085e25..697df0ef 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # AimDB Makefile # Simple automation for common development tasks -.PHONY: help build test clean clean-embedded fmt fmt-check clippy doc all check test-embedded test-wasm wasm wasm-test wasm-test-deps examples deny audit security publish publish-check readme-check codegen-drift check-no-sim check-no-globals check-toolchain-pin bench-gate +.PHONY: ros2-interop help build test clean clean-embedded fmt fmt-check clippy doc all check test-embedded test-wasm wasm wasm-test wasm-test-deps examples deny audit security publish publish-check readme-check codegen-drift check-no-sim check-no-globals check-toolchain-pin bench-gate .DEFAULT_GOAL := help # Separate target dir for embedded checks so an interrupted example build @@ -31,6 +31,10 @@ SYNC_NO_STD_FORBIDDEN := tokio|libc # executor, network stack, adapter or logger may reach its graph. MQTT_EMBEDDED_FORBIDDEN := embassy-net|embassy-executor|embassy-time|static_cell|aimdb-embassy-adapter|defmt|embedded-hal-async MQTT_DEPENDENCY_FORBIDDEN := embedded-io|embedded-hal|tokio +# The `zenoh` crate (not `zenoh-nostd`/`zenoh-keyexpr`) and tokio are std-only. +ZENOH_EMBEDDED_FORBIDDEN := (^|[^-])zenoh v[0-9]|tokio +# `cargo deny check` sees default features only, which leave `zenoh` out. +ZENOH_DENY := cargo deny --features "std,transport-tls,transport-quic,transport-ws,auth-usrpwd" --manifest-path aimdb-zenoh-connector/Cargo.toml # The guards below grep `cargo tree`'s stdout only — never `2>&1`. Cargo writes # progress to stderr, so on a cold cache "Downloaded embedded-hal-nb v1.0.0" # matches these patterns and fails the build. @@ -55,6 +59,7 @@ help: @printf " test-embedded Test embedded/MCU cross-compilation compatibility\n" @printf " test-wasm Test WASM cross-compilation compatibility\n" @printf " readme-check Verify the README quickstart matches its compiled example\n" + @printf " ros2-interop ros2:// against a ROS 2 distribution in Docker (DISTRO=lyrical)\n" @printf " codegen-drift Compile codegen output against the workspace API\n" @printf " bench-gate Assert connector allocation counts (b0_alloc_connector)\n" @printf "\n" @@ -78,8 +83,14 @@ help: ## Core commands build: @printf "$(GREEN)Building AimDB (all valid combinations)...$(NC)\n" + @printf "$(YELLOW) → Building aimdb-cdr (alloc, no_std)$(NC)\n" + cargo build --package aimdb-cdr + cargo build --package aimdb-cdr --no-default-features + @printf "$(YELLOW) → Building aimdb-zenoh-connector (std, embedded)$(NC)\n" + cargo build --package aimdb-zenoh-connector --features "std" + cargo build --package aimdb-zenoh-connector --no-default-features --features "embedded" @printf "$(YELLOW) → Building aimdb-data-contracts (std)$(NC)\n" - cargo build --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard" + cargo build --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard,linkable-cdr,ros2" @printf "$(YELLOW) → Building aimdb-data-contracts (no_std)$(NC)\n" cargo build --package aimdb-data-contracts --no-default-features --features alloc @printf "$(YELLOW) → Building aimdb-data-contracts (no_std + format-neutral linkable)$(NC)\n" @@ -149,14 +160,21 @@ build: test: @printf "$(GREEN)Running all tests (valid combinations)...$(NC)\n" + @printf "$(YELLOW) → Testing aimdb-cdr (alloc, no_std)$(NC)\n" + cargo test --package aimdb-cdr + cargo test --package aimdb-cdr --no-default-features @printf "$(YELLOW) → Testing aimdb-data-contracts (std)$(NC)\n" - cargo test --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard" + cargo test --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard,linkable-cdr,ros2" @printf "$(YELLOW) → Testing aimdb-data-contracts (no_std + alloc + format-neutral linkable)$(NC)\n" cargo test --package aimdb-data-contracts --no-default-features --features alloc,linkable @printf "$(YELLOW) → Testing aimdb-data-contracts (no_std + alloc + linkable-postcard)$(NC)\n" cargo test --package aimdb-data-contracts --no-default-features --features alloc,linkable-postcard @printf "$(YELLOW) → Testing aimdb-data-contracts (no_std + alloc + linkable-json + migratable)$(NC)\n" cargo test --package aimdb-data-contracts --no-default-features --features alloc,linkable-json,migratable + @printf "$(YELLOW) → Testing aimdb-data-contracts (no_std + alloc + ros2)$(NC)\n" + cargo test --package aimdb-data-contracts --no-default-features --features alloc,ros2 + @printf "$(YELLOW) → Testing aimdb-data-contracts (no_std + alloc + linkable-cdr)$(NC)\n" + cargo test --package aimdb-data-contracts --no-default-features --features alloc,linkable-cdr @printf "$(YELLOW) → Testing aimdb-core (no_std + alloc)$(NC)\n" cargo test --package aimdb-core --no-default-features --features alloc @printf "$(YELLOW) → Testing aimdb-core (std platform)$(NC)\n" @@ -219,6 +237,10 @@ test: cargo test --package aimdb-persistence @printf "$(YELLOW) → Testing persistence SQLite backend$(NC)\n" cargo test --package aimdb-persistence-sqlite + @printf "$(YELLOW) → Testing Zenoh connector (std)$(NC)\n" + cargo test --package aimdb-zenoh-connector --features "std" + @printf "$(YELLOW) → Testing Zenoh connector (embedded, no_std+alloc)$(NC)\n" + cargo test --package aimdb-zenoh-connector --no-default-features --features "embedded" @printf "$(YELLOW) → Testing MQTT connector (tokio, no TLS backend)$(NC)\n" cargo test --package aimdb-mqtt-connector --features "std" @printf "$(YELLOW) → Testing MQTT connector (tokio + native-tls)$(NC)\n" @@ -264,7 +286,7 @@ test: fmt: @printf "$(GREEN)Formatting code (workspace members only)...$(NC)\n" - @for pkg in aimdb-derive aimdb-data-contracts aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-wasm-adapter aimdb-sync aimdb-persistence aimdb-persistence-sqlite aimdb-mqtt-connector aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector aimdb-serial-connector aimdb-tcp-connector aimdb-codegen aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo embassy-serial-connector-demo embassy-bench-stm32h5 weather-mesh-common weather-hub weather-station-alpha weather-station-beta hello-mailbox hello-mailbox-async hello-single-latest hello-single-latest-async hello-spmc-ring hello-spmc-ring-async aimdb-bench; do \ + @for pkg in aimdb-derive aimdb-cdr aimdb-data-contracts aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-wasm-adapter aimdb-sync aimdb-persistence aimdb-persistence-sqlite aimdb-mqtt-connector aimdb-zenoh-connector aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector aimdb-serial-connector aimdb-tcp-connector aimdb-codegen aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo embassy-serial-connector-demo embassy-bench-stm32h5 weather-mesh-common weather-hub weather-station-alpha weather-station-beta hello-mailbox hello-mailbox-async hello-single-latest hello-single-latest-async hello-spmc-ring hello-spmc-ring-async aimdb-bench; do \ printf "$(YELLOW) → Formatting $$pkg$(NC)\n"; \ cargo fmt -p $$pkg 2>/dev/null || true; \ done @@ -273,7 +295,7 @@ fmt: fmt-check: @printf "$(GREEN)Checking code formatting (workspace members only)...$(NC)\n" @FAILED=0; \ - for pkg in aimdb-derive aimdb-data-contracts aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-wasm-adapter aimdb-sync aimdb-persistence aimdb-persistence-sqlite aimdb-mqtt-connector aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector aimdb-serial-connector aimdb-tcp-connector aimdb-codegen aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo embassy-serial-connector-demo embassy-bench-stm32h5 weather-mesh-common weather-hub weather-station-alpha weather-station-beta hello-mailbox hello-mailbox-async hello-single-latest hello-single-latest-async hello-spmc-ring hello-spmc-ring-async aimdb-bench; do \ + for pkg in aimdb-derive aimdb-cdr aimdb-data-contracts aimdb-core aimdb-client aimdb-embassy-adapter aimdb-tokio-adapter aimdb-wasm-adapter aimdb-sync aimdb-persistence aimdb-persistence-sqlite aimdb-mqtt-connector aimdb-zenoh-connector aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector aimdb-serial-connector aimdb-tcp-connector aimdb-codegen aimdb-cli aimdb-mcp sync-api-demo tokio-mqtt-connector-demo embassy-mqtt-connector-demo tokio-knx-connector-demo embassy-knx-connector-demo embassy-serial-connector-demo embassy-bench-stm32h5 weather-mesh-common weather-hub weather-station-alpha weather-station-beta hello-mailbox hello-mailbox-async hello-single-latest hello-single-latest-async hello-spmc-ring hello-spmc-ring-async aimdb-bench; do \ printf "$(YELLOW) → Checking $$pkg$(NC)\n"; \ if ! cargo fmt -p $$pkg -- --check 2>&1; then \ printf "$(RED)❌ Formatting check failed for $$pkg$(NC)\n"; \ @@ -290,8 +312,11 @@ clippy: @printf "$(GREEN)Running clippy (all valid combinations)...$(NC)\n" @printf "$(YELLOW) → Clippy on aimdb-derive$(NC)\n" cargo clippy --package aimdb-derive --all-targets -- -D warnings + @printf "$(YELLOW) → Clippy on aimdb-cdr (alloc, no_std)$(NC)\n" + cargo clippy --package aimdb-cdr --all-targets -- -D warnings + cargo clippy --package aimdb-cdr --no-default-features --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-data-contracts (std)$(NC)\n" - cargo clippy --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard" --all-targets -- -D warnings + cargo clippy --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard,linkable-cdr,ros2" --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-data-contracts (no_std + alloc)$(NC)\n" cargo clippy --package aimdb-data-contracts --no-default-features --features alloc -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-data-contracts (no_std + alloc + format-neutral linkable)$(NC)\n" @@ -300,6 +325,10 @@ clippy: cargo clippy --package aimdb-data-contracts --no-default-features --features alloc,linkable-postcard --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-data-contracts (no_std + alloc + linkable-json + migratable)$(NC)\n" cargo clippy --package aimdb-data-contracts --no-default-features --features alloc,linkable-json,migratable --all-targets -- -D warnings + @printf "$(YELLOW) → Clippy on aimdb-data-contracts (no_std + alloc + ros2)$(NC)\n" + cargo clippy --package aimdb-data-contracts --no-default-features --features alloc,ros2 --all-targets -- -D warnings + @printf "$(YELLOW) → Clippy on aimdb-data-contracts (no_std + alloc + linkable-cdr)$(NC)\n" + cargo clippy --package aimdb-data-contracts --no-default-features --features alloc,linkable-cdr --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc)$(NC)\n" cargo clippy --package aimdb-core --no-default-features --features alloc --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on aimdb-core (no_std + alloc + remote)$(NC)\n" @@ -360,6 +389,12 @@ clippy: cargo clippy --package aimdb-knx-connector --no-default-features --features "std" --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on KNX connector (neutral, no_std+alloc)$(NC)\n" cargo clippy --package aimdb-knx-connector --target thumbv7em-none-eabihf --no-default-features --features "connector" -- -D warnings + @printf "$(YELLOW) → Clippy on Zenoh connector (std)$(NC)\n" + cargo clippy --package aimdb-zenoh-connector --features "std" --all-targets -- -D warnings + cargo clippy --package aimdb-zenoh-connector --features "std,tracing,transport-tls,transport-quic,transport-ws,auth-usrpwd" -- -D warnings + @printf "$(YELLOW) → Clippy on Zenoh connector (embedded, no_std+alloc)$(NC)\n" + cargo clippy --package aimdb-zenoh-connector --no-default-features --features "embedded" --all-targets -- -D warnings + cargo clippy --package aimdb-zenoh-connector --target thumbv7em-none-eabihf --no-default-features --features "embedded" -- -D warnings @printf "$(YELLOW) → Clippy on MQTT connector (tokio, no TLS backend)$(NC)\n" cargo clippy --package aimdb-mqtt-connector --features "std" --all-targets -- -D warnings @printf "$(YELLOW) → Clippy on MQTT connector (tokio + native-tls)$(NC)\n" @@ -428,11 +463,12 @@ doc: @mkdir -p target/doc-final/cloud @mkdir -p target/doc-final/embedded @printf "$(YELLOW) → Building cloud/edge documentation$(NC)\n" - cargo doc --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard" --no-deps + cargo doc --package aimdb-data-contracts --features "std,simulatable,migratable,observable,linkable-json,linkable-postcard,linkable-cdr,ros2" --no-deps cargo doc --package aimdb-core --features "std,tracing,observability" --no-deps cargo doc --package aimdb-tokio-adapter --features "tokio-runtime,tracing,observability,net,embedded-io" --no-deps cargo doc --package aimdb-sync --no-deps cargo doc --package aimdb-mqtt-connector --features "std" --no-deps + cargo doc --package aimdb-zenoh-connector --features "std" --no-deps cargo doc --package aimdb-knx-connector --no-default-features --features "std" --no-deps cargo doc --package aimdb-codegen --no-deps cargo doc --package aimdb-cli --no-deps @@ -449,14 +485,17 @@ doc: cargo doc --package aimdb-tcp-connector --no-default-features --features "std" --no-deps cargo doc --package aimdb-client --features "transport-serial,transport-tcp" --no-deps cargo doc --package aimdb-derive --no-deps + cargo doc --package aimdb-cdr --no-deps @cp -r target/doc/* target/doc-final/cloud/ @printf "$(YELLOW) → Building embedded documentation$(NC)\n" cargo doc --package aimdb-core --no-default-features --features alloc --no-deps + cargo doc --package aimdb-cdr --no-default-features --no-deps cargo doc --package aimdb-embassy-adapter --features "embassy-runtime,net" --no-deps cargo doc --package aimdb-mqtt-connector --no-default-features --features "embedded" --no-deps cargo doc --package aimdb-mqtt-connector --no-default-features --features "embedded-tls" --no-deps cargo doc --package aimdb-mqtt-connector --no-default-features --features "embassy-runtime" --no-deps cargo doc --package aimdb-mqtt-connector --no-default-features --features "embassy-tls" --no-deps + cargo doc --package aimdb-zenoh-connector --no-default-features --features "embedded" --no-deps cargo doc --package aimdb-knx-connector --no-default-features --features "connector" --no-deps cargo doc --package aimdb-serial-connector --no-default-features --features "connector" --no-deps cargo doc --package aimdb-tcp-connector --no-default-features --features "connector" --no-deps @@ -486,6 +525,9 @@ test-wasm: test-embedded: @printf "$(BLUE)Testing embedded/MCU cross-compilation compatibility...$(NC)\n" + @printf "$(YELLOW) → Checking aimdb-cdr (alloc, no_std) on thumbv7em-none-eabihf target$(NC)\n" + cargo check --package aimdb-cdr --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) + cargo check --package aimdb-cdr --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features @printf "$(YELLOW) → Checking aimdb-data-contracts (no_std + alloc) on thumbv7em-none-eabihf target$(NC)\n" cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc @printf "$(YELLOW) → Checking aimdb-data-contracts (no_std + alloc + format-neutral linkable) on thumbv7em-none-eabihf target$(NC)\n" @@ -494,6 +536,10 @@ test-embedded: cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc,linkable-postcard @printf "$(YELLOW) → Checking aimdb-data-contracts (no_std + alloc + linkable-json + migratable) on thumbv7em-none-eabihf target$(NC)\n" cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc,linkable-json,migratable + @printf "$(YELLOW) → Checking aimdb-data-contracts (no_std + alloc + ros2) on thumbv7em-none-eabihf target$(NC)\n" + cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc,ros2 + @printf "$(YELLOW) → Checking aimdb-data-contracts (no_std + alloc + linkable-cdr) on thumbv7em-none-eabihf target$(NC)\n" + cargo check --package aimdb-data-contracts --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features alloc,linkable-cdr @printf "$(YELLOW) → Checking weather-mesh-common (no_std migratable, real TemperatureV1ToV2 chain, no direct serde_json dep) on thumbv7em-none-eabihf target$(NC)\n" cargo check --package weather-mesh-common --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features migratable @printf "$(YELLOW) → Checking aimdb-core (no_std minimal) on thumbv7em-none-eabihf target$(NC)\n" @@ -545,6 +591,31 @@ test-embedded: printf '%s\n' "$$out" | grep -iE '$(MQTT_DEPENDENCY_FORBIDDEN)'; exit 1; \ fi @printf "$(BLUE)✓ mountain-mqtt is the codec alone$(NC)\n" + @printf "$(YELLOW) → Checking aimdb-zenoh-connector (embedded backend) on thumbv7em-none-eabihf target$(NC)\n" + cargo check --package aimdb-zenoh-connector --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "embedded" + @printf "$(YELLOW) → Asserting no std-only Zenoh crates in the embedded Zenoh backend$(NC)\n" + @err=$$(mktemp); \ + out=$$(cargo tree -p aimdb-zenoh-connector --target thumbv7em-none-eabihf --no-default-features --features "embedded" -e features,no-dev 2>$$err) || { \ + printf "$(RED)✗ cargo tree failed — refusing to pass vacuously:$(NC)\n"; \ + cat $$err; rm -f $$err; exit 1; \ + }; \ + rm -f $$err; \ + if printf '%s\n' "$$out" | grep -qE '$(ZENOH_EMBEDDED_FORBIDDEN)'; then \ + printf "$(RED)✗ a std-only crate leaked into the embedded Zenoh graph$(NC)\n"; \ + printf '%s\n' "$$out" | grep -E '$(ZENOH_EMBEDDED_FORBIDDEN)'; exit 1; \ + fi + @printf "$(BLUE)✓ embedded Zenoh graph is free of the zenoh crate and tokio$(NC)\n" + @printf "$(YELLOW) → Asserting the std Zenoh backend leaves transport compression off$(NC)\n" + @err=$$(mktemp); \ + out=$$(cargo tree -p aimdb-zenoh-connector --features "std,tracing,transport-tls,transport-quic,transport-ws" -e features -i zenoh-transport 2>$$err) || { \ + printf "$(RED)✗ cargo tree failed — refusing to pass vacuously:$(NC)\n"; \ + cat $$err; rm -f $$err; exit 1; \ + }; \ + rm -f $$err; \ + if printf '%s\n' "$$out" | grep -q 'zenoh-transport feature "transport_compression"'; then \ + printf "$(RED)✗ zenoh transport compression is enabled; RUSTSEC-2026-0041 is ignored only because it is not$(NC)\n"; exit 1; \ + fi + @printf "$(BLUE)✓ zenoh transport compression is off$(NC)\n" @printf "$(YELLOW) → Checking aimdb-mqtt-connector (Embassy bundle) on thumbv7em-none-eabihf target$(NC)\n" cargo check --package aimdb-mqtt-connector --target thumbv7em-none-eabihf --target-dir $(EMBEDDED_CHECK_TARGET_DIR) --no-default-features --features "embassy-runtime" @printf "$(YELLOW) → Checking aimdb-mqtt-connector (Embassy + defmt) on thumbv7em-none-eabihf target$(NC)\n" @@ -629,6 +700,8 @@ deny: @printf "$(YELLOW) → Checking banned dependencies$(NC)\n" @printf "$(YELLOW) → Checking dependency sources$(NC)\n" cargo deny check + @printf "$(YELLOW) → Checking the Zenoh connector's std graph (not a default feature)$(NC)\n" + $(ZENOH_DENY) check audit: @printf "$(GREEN)Auditing dependencies for vulnerabilities...$(NC)\n" @@ -674,6 +747,7 @@ publish-check: PUBLISH_ORDER := \ aimdb-codegen \ aimdb-derive \ + aimdb-cdr \ aimdb-core \ aimdb-data-contracts \ aimdb-embassy-adapter \ @@ -682,6 +756,7 @@ PUBLISH_ORDER := \ aimdb-uds-connector \ aimdb-knx-connector \ aimdb-mqtt-connector \ + aimdb-zenoh-connector \ aimdb-persistence-sqlite \ aimdb-serial-connector \ aimdb-sync \ @@ -759,6 +834,15 @@ bench-gate: @printf "$(GREEN)Checking connector allocation counts...$(NC)\n" cargo bench --package aimdb-bench --bench b0_alloc_connector +## Interop +# ros2:// against a real ROS 2 distribution (rmw_zenohd and the ros2 CLI in +# Docker, host networking). DISTRO is a ros: image tag. +DISTRO ?= lyrical +ros2-interop: + @printf "$(GREEN)ROS 2 interop on $(DISTRO)...$(NC)\n" + cargo build --package aimdb-zenoh-connector --features "std" --examples + ./aimdb-zenoh-connector/tests/interop/ros2_interop.sh $(DISTRO) + ## Drift guards # The README quickstart is compiled as examples/readme-quickstart; this target # fails when the README code block and the example diverge, or when the @@ -820,10 +904,10 @@ check-no-sim: # Applications may, so `tools/`, `examples/` and codegen's generated `main` are # not scanned. The one exception: the fork detector owns the runtime thread it # protects. A positive control keeps the guard from failing open. -GLOBALS_SCANNED := aimdb-core aimdb-data-contracts aimdb-derive aimdb-client \ +GLOBALS_SCANNED := aimdb-core aimdb-cdr aimdb-data-contracts aimdb-derive aimdb-client \ aimdb-tokio-adapter aimdb-embassy-adapter aimdb-wasm-adapter aimdb-sync \ aimdb-persistence aimdb-persistence-sqlite aimdb-mqtt-connector \ - aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector \ + aimdb-zenoh-connector aimdb-knx-connector aimdb-websocket-connector aimdb-uds-connector \ aimdb-serial-connector aimdb-tcp-connector GLOBALS_PATTERN := tracing_subscriber::|set_global_default|set_boxed_logger|set_logger\(|set_max_level|panic::set_hook|panic::take_hook|pthread_atfork|sigaction|signal_hook|set_var\( GLOBALS_ALLOWED := aimdb-sync/src/fork\.rs diff --git a/README.md b/README.md index 2d510adb..18e66f18 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ docker compose up | Containers / Kubernetes | Tokio | `aimdb-tokio-adapter` | ~10 MB+ | | Browser | WASM | `aimdb-wasm-adapter` | ~2 MB+ | -**Connectors today:** MQTT · KNX · WebSocket · TCP · Serial · Unix sockets. Kafka and Modbus are planned. A new connector is one trait impl. +**Connectors today:** MQTT · KNX · Zenoh and ROS 2 · WebSocket · TCP · Serial · Unix sockets. Kafka and Modbus are planned. A new connector is one trait impl. ## Under the hood diff --git a/aimdb-cdr/CHANGELOG.md b/aimdb-cdr/CHANGELOG.md new file mode 100644 index 00000000..5ce47c8d --- /dev/null +++ b/aimdb-cdr/CHANGELOG.md @@ -0,0 +1,21 @@ +# Changelog - aimdb-cdr + +All notable changes to the `aimdb-cdr` crate will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- **First release: serde for OMG CDR (XCDR1)**, the ROS 2 wire format, with + its 4-byte encapsulation header. `no_std`, `alloc` optional. + - `to_slice` encodes little-endian into caller storage without allocating; + `to_vec` needs `alloc`. + - `from_bytes` decodes both byte orders, taken from the header (`CDR_LE` or + `CDR_BE`); any other representation is an error. + - Alignment is measured from the end of the header; strings carry a `u32` + length including the NUL, sequences a `u32` count, fixed arrays none. + - Tested against golden bytes, byte for byte against `hiroz-cdr` for + little-endian output, and with random and malformed input. diff --git a/aimdb-cdr/Cargo.toml b/aimdb-cdr/Cargo.toml new file mode 100644 index 00000000..ba682107 --- /dev/null +++ b/aimdb-cdr/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "aimdb-cdr" +version = "0.1.0" +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +description = "no_std serde encoding for OMG CDR (XCDR1), the ROS 2 wire format" +keywords = ["cdr", "ros2", "serde", "no-std", "aimdb"] +categories = ["encoding", "no-std", "embedded"] + +[features] +default = ["alloc"] +# `to_vec`, owned `String`/`Vec` decoding, and error messages from serde impls. +alloc = ["serde/alloc"] + +[dependencies] +serde = { version = "1.0", default-features = false } + +[dev-dependencies] +serde = { version = "1.0", features = ["derive"] } +# Reference encoder: byte-for-byte oracle for the little-endian output. +hiroz-cdr = "0.2" diff --git a/aimdb-cdr/README.md b/aimdb-cdr/README.md new file mode 100644 index 00000000..1a24bccf --- /dev/null +++ b/aimdb-cdr/README.md @@ -0,0 +1,24 @@ +# aimdb-cdr + +`no_std` serde encoding for OMG CDR (XCDR1) with the 4-byte encapsulation +header — the payload format ROS 2 puts on the wire. + +- Encodes little-endian; decodes little- and big-endian. +- `to_slice` writes into caller storage without allocating. `to_vec` and owned + `String`/`Vec` fields need the default `alloc` feature. +- Strings carry a `u32` length including the NUL; sequences a `u32` count; + fixed arrays and structs no prefix. Alignment is measured from the end of the + header. + +```rust +#[derive(serde::Serialize, serde::Deserialize, PartialEq, Debug)] +struct Temperature { temperature: f64, variance: f64 } + +let mut buf = [0u8; 20]; +let len = aimdb_cdr::to_slice(&Temperature { temperature: 21.5, variance: 0.0 }, &mut buf).unwrap(); +let back: Temperature = aimdb_cdr::from_bytes(&buf[..len]).unwrap(); +assert_eq!(back.temperature, 21.5); +``` + +`Option`, enums, maps and `char` have no XCDR1 mapping in ROS 2 and are +rejected with `Error::Unsupported`. diff --git a/aimdb-cdr/src/de.rs b/aimdb-cdr/src/de.rs new file mode 100644 index 00000000..a55ac97b --- /dev/null +++ b/aimdb-cdr/src/de.rs @@ -0,0 +1,272 @@ +use serde::de::{self, DeserializeSeed, Visitor}; + +use crate::{Error, Result}; + +/// XCDR1 body deserializer. `pos` counts from the end of the header. +pub(crate) struct Deserializer<'de> { + input: &'de [u8], + pos: usize, + big_endian: bool, +} + +macro_rules! read_primitive { + ($name:ident, $ty:ty) => { + fn $name(&mut self) -> Result<$ty> { + let bytes = self.primitive::<{ core::mem::size_of::<$ty>() }>()?; + Ok(if self.big_endian { + <$ty>::from_be_bytes(bytes) + } else { + <$ty>::from_le_bytes(bytes) + }) + } + }; +} + +impl<'de> Deserializer<'de> { + pub(crate) fn new(input: &'de [u8], big_endian: bool) -> Self { + Self { + input, + pos: 0, + big_endian, + } + } + + fn remaining(&self) -> usize { + self.input.len() - self.pos + } + + fn take(&mut self, len: usize) -> Result<&'de [u8]> { + let end = self.pos.checked_add(len).ok_or(Error::UnexpectedEof)?; + let bytes = self.input.get(self.pos..end).ok_or(Error::UnexpectedEof)?; + self.pos = end; + Ok(bytes) + } + + fn align(&mut self, alignment: usize) -> Result<()> { + let padding = (alignment - self.pos % alignment) % alignment; + self.take(padding).map(drop) + } + + fn primitive(&mut self) -> Result<[u8; N]> { + self.align(N)?; + let mut bytes = [0; N]; + bytes.copy_from_slice(self.take(N)?); + Ok(bytes) + } + + read_primitive!(read_u16, u16); + read_primitive!(read_u32, u32); + read_primitive!(read_u64, u64); + read_primitive!(read_i16, i16); + read_primitive!(read_i32, i32); + read_primitive!(read_i64, i64); + read_primitive!(read_f32, f32); + read_primitive!(read_f64, f64); + + fn read_u8(&mut self) -> Result { + Ok(self.take(1)?[0]) + } + + /// A `u32` length prefix. Every ROS element takes at least one byte, so a + /// count beyond the remaining input is rejected before anything allocates. + fn read_length(&mut self) -> Result { + let len = usize::try_from(self.read_u32()?).map_err(|_| Error::UnexpectedEof)?; + if len > self.remaining() { + return Err(Error::UnexpectedEof); + } + Ok(len) + } + + fn read_str(&mut self) -> Result<&'de str> { + let len = self.read_length()?; + if len == 0 { + return Ok(""); + } + let (text, nul) = self.take(len)?.split_at(len - 1); + if nul != [0] { + return Err(Error::MissingNul); + } + core::str::from_utf8(text).map_err(|_| Error::InvalidUtf8) + } +} + +impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> { + type Error = Error; + + fn deserialize_any>(self, _visitor: V) -> Result { + Err(Error::Unsupported("self-describing deserialize")) + } + + fn deserialize_bool>(self, visitor: V) -> Result { + match self.read_u8()? { + 0 => visitor.visit_bool(false), + 1 => visitor.visit_bool(true), + other => Err(Error::InvalidBool(other)), + } + } + + fn deserialize_i8>(self, visitor: V) -> Result { + visitor.visit_i8(i8::from_le_bytes([self.read_u8()?])) + } + + fn deserialize_i16>(self, visitor: V) -> Result { + visitor.visit_i16(self.read_i16()?) + } + + fn deserialize_i32>(self, visitor: V) -> Result { + visitor.visit_i32(self.read_i32()?) + } + + fn deserialize_i64>(self, visitor: V) -> Result { + visitor.visit_i64(self.read_i64()?) + } + + fn deserialize_u8>(self, visitor: V) -> Result { + visitor.visit_u8(self.read_u8()?) + } + + fn deserialize_u16>(self, visitor: V) -> Result { + visitor.visit_u16(self.read_u16()?) + } + + fn deserialize_u32>(self, visitor: V) -> Result { + visitor.visit_u32(self.read_u32()?) + } + + fn deserialize_u64>(self, visitor: V) -> Result { + visitor.visit_u64(self.read_u64()?) + } + + fn deserialize_f32>(self, visitor: V) -> Result { + visitor.visit_f32(self.read_f32()?) + } + + fn deserialize_f64>(self, visitor: V) -> Result { + visitor.visit_f64(self.read_f64()?) + } + + fn deserialize_char>(self, _visitor: V) -> Result { + Err(Error::Unsupported("char")) + } + + fn deserialize_str>(self, visitor: V) -> Result { + visitor.visit_borrowed_str(self.read_str()?) + } + + fn deserialize_string>(self, visitor: V) -> Result { + self.deserialize_str(visitor) + } + + fn deserialize_bytes>(self, visitor: V) -> Result { + let len = self.read_length()?; + visitor.visit_borrowed_bytes(self.take(len)?) + } + + fn deserialize_byte_buf>(self, visitor: V) -> Result { + self.deserialize_bytes(visitor) + } + + fn deserialize_option>(self, _visitor: V) -> Result { + Err(Error::Unsupported("Option")) + } + + fn deserialize_unit>(self, visitor: V) -> Result { + visitor.visit_unit() + } + + fn deserialize_unit_struct>( + self, + _name: &'static str, + visitor: V, + ) -> Result { + visitor.visit_unit() + } + + fn deserialize_newtype_struct>( + self, + _name: &'static str, + visitor: V, + ) -> Result { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq>(self, visitor: V) -> Result { + let len = self.read_length()?; + visitor.visit_seq(Elements { + de: self, + left: len, + }) + } + + fn deserialize_tuple>(self, len: usize, visitor: V) -> Result { + visitor.visit_seq(Elements { + de: self, + left: len, + }) + } + + fn deserialize_tuple_struct>( + self, + _name: &'static str, + len: usize, + visitor: V, + ) -> Result { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map>(self, _visitor: V) -> Result { + Err(Error::Unsupported("map")) + } + + fn deserialize_struct>( + self, + _name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_enum>( + self, + _name: &'static str, + _variants: &'static [&'static str], + _visitor: V, + ) -> Result { + Err(Error::Unsupported("enum")) + } + + fn deserialize_identifier>(self, _visitor: V) -> Result { + Err(Error::Unsupported("identifier")) + } + + fn deserialize_ignored_any>(self, _visitor: V) -> Result { + Err(Error::Unsupported("ignored field")) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +/// Fixed-count access for sequences, arrays and struct fields. +struct Elements<'a, 'de> { + de: &'a mut Deserializer<'de>, + left: usize, +} + +impl<'de> de::SeqAccess<'de> for Elements<'_, 'de> { + type Error = Error; + + fn next_element_seed>(&mut self, seed: T) -> Result> { + if self.left == 0 { + return Ok(None); + } + self.left -= 1; + seed.deserialize(&mut *self.de).map(Some) + } + + fn size_hint(&self) -> Option { + Some(self.left.min(self.de.remaining())) + } +} diff --git a/aimdb-cdr/src/error.rs b/aimdb-cdr/src/error.rs new file mode 100644 index 00000000..906e9027 --- /dev/null +++ b/aimdb-cdr/src/error.rs @@ -0,0 +1,79 @@ +use core::fmt; + +/// Result alias for this crate. +pub type Result = core::result::Result; + +/// Encode or decode failure. +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum Error { + /// The output slice is too small. + BufferTooSmall, + /// The input ended early, or a length prefix exceeds the input. + UnexpectedEof, + /// The representation identifier is not `CDR_LE` or `CDR_BE`. + InvalidHeader([u8; 2]), + /// A `bool` byte other than 0 or 1. + InvalidBool(u8), + /// A string is not UTF-8. + InvalidUtf8, + /// A string is not NUL-terminated. + MissingNul, + /// A length does not fit the `u32` prefix. + LengthOverflow, + /// A sequence was serialized without a known length. + UnknownLength, + /// A serde construct with no CDR mapping. + Unsupported(&'static str), + /// A serde impl reported an error (message dropped without `alloc`). + Custom, + /// A serde impl reported an error. + #[cfg(feature = "alloc")] + Message(alloc::string::String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::BufferTooSmall => f.write_str("output buffer too small"), + Self::UnexpectedEof => f.write_str("unexpected end of input"), + Self::InvalidHeader(id) => write!(f, "unsupported CDR representation {id:02x?}"), + Self::InvalidBool(b) => write!(f, "invalid bool byte {b}"), + Self::InvalidUtf8 => f.write_str("string is not UTF-8"), + Self::MissingNul => f.write_str("string is not NUL-terminated"), + Self::LengthOverflow => f.write_str("length exceeds u32"), + Self::UnknownLength => f.write_str("sequence length unknown"), + Self::Unsupported(what) => write!(f, "{what} has no CDR mapping"), + Self::Custom => f.write_str("serde error"), + #[cfg(feature = "alloc")] + Self::Message(msg) => f.write_str(msg), + } + } +} + +impl core::error::Error for Error {} + +impl Error { + fn custom(_msg: T) -> Self { + #[cfg(feature = "alloc")] + { + Self::Message(alloc::string::ToString::to_string(&_msg)) + } + #[cfg(not(feature = "alloc"))] + { + Self::Custom + } + } +} + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + Error::custom(msg) + } +} + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self { + Error::custom(msg) + } +} diff --git a/aimdb-cdr/src/lib.rs b/aimdb-cdr/src/lib.rs new file mode 100644 index 00000000..257efd5f --- /dev/null +++ b/aimdb-cdr/src/lib.rs @@ -0,0 +1,68 @@ +#![doc = include_str!("../README.md")] +#![cfg_attr( + not(test), + deny(clippy::unwrap_used, clippy::expect_used, clippy::panic) +)] +#![no_std] + +#[cfg(feature = "alloc")] +extern crate alloc; + +mod de; +mod error; +mod ser; + +pub use error::{Error, Result}; + +/// Encapsulation header for little-endian XCDR1 (`CDR_LE`), the only one this +/// crate writes. +pub const HEADER_LE: [u8; 4] = [0x00, 0x01, 0x00, 0x00]; + +const HEADER_LEN: usize = HEADER_LE.len(); + +/// Encodes `value` with its header into `out`, returning the bytes written. +/// +/// Fails with [`Error::BufferTooSmall`] if `out` cannot hold it; `out` is then +/// partially written. +pub fn to_slice(value: &T, out: &mut [u8]) -> Result +where + T: serde::Serialize + ?Sized, +{ + let (header, body) = out + .split_at_mut_checked(HEADER_LEN) + .ok_or(Error::BufferTooSmall)?; + header.copy_from_slice(&HEADER_LE); + let mut serializer = ser::Serializer::new(ser::SliceWriter::new(body)); + value.serialize(&mut serializer)?; + Ok(HEADER_LEN + serializer.position()) +} + +/// Encodes `value` with its header into a new `Vec`. +#[cfg(feature = "alloc")] +pub fn to_vec(value: &T) -> Result> +where + T: serde::Serialize + ?Sized, +{ + let mut out = alloc::vec::Vec::from(HEADER_LE); + value.serialize(&mut ser::Serializer::new(&mut out))?; + Ok(out) +} + +/// Decodes a value from an encapsulated payload. +/// +/// The byte order comes from the header (`CDR_LE` or `CDR_BE`); any other +/// representation is [`Error::InvalidHeader`]. Trailing bytes are ignored. +pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result +where + T: serde::Deserialize<'de>, +{ + let (header, body) = bytes + .split_at_checked(HEADER_LEN) + .ok_or(Error::UnexpectedEof)?; + let big_endian = match [header[0], header[1]] { + [0x00, 0x01] => false, + [0x00, 0x00] => true, + other => return Err(Error::InvalidHeader(other)), + }; + T::deserialize(&mut de::Deserializer::new(body, big_endian)) +} diff --git a/aimdb-cdr/src/ser.rs b/aimdb-cdr/src/ser.rs new file mode 100644 index 00000000..56f57851 --- /dev/null +++ b/aimdb-cdr/src/ser.rs @@ -0,0 +1,292 @@ +use serde::ser::{self, Serialize}; + +use crate::{Error, Result}; + +/// Byte sink behind the serializer. +pub(crate) trait Write { + fn write_all(&mut self, bytes: &[u8]) -> Result<()>; +} + +/// Writes into a fixed slice; overflow is [`Error::BufferTooSmall`]. +pub(crate) struct SliceWriter<'a> { + buf: &'a mut [u8], + len: usize, +} + +impl<'a> SliceWriter<'a> { + pub(crate) fn new(buf: &'a mut [u8]) -> Self { + Self { buf, len: 0 } + } +} + +impl Write for SliceWriter<'_> { + fn write_all(&mut self, bytes: &[u8]) -> Result<()> { + let end = self.len + bytes.len(); + self.buf + .get_mut(self.len..end) + .ok_or(Error::BufferTooSmall)? + .copy_from_slice(bytes); + self.len = end; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl Write for &mut alloc::vec::Vec { + fn write_all(&mut self, bytes: &[u8]) -> Result<()> { + self.extend_from_slice(bytes); + Ok(()) + } +} + +/// Little-endian XCDR1 body serializer. `pos` counts from the end of the +/// header, which is where CDR alignment is measured from. +pub(crate) struct Serializer { + out: W, + pos: usize, +} + +impl Serializer { + pub(crate) fn new(out: W) -> Self { + Self { out, pos: 0 } + } + + pub(crate) fn position(&self) -> usize { + self.pos + } + + fn write(&mut self, bytes: &[u8]) -> Result<()> { + self.out.write_all(bytes)?; + self.pos += bytes.len(); + Ok(()) + } + + fn align(&mut self, alignment: usize) -> Result<()> { + let padding = (alignment - self.pos % alignment) % alignment; + self.write(&[0; 8][..padding]) + } + + fn primitive(&mut self, bytes: [u8; N]) -> Result<()> { + self.align(N)?; + self.write(&bytes) + } + + fn length(&mut self, len: usize) -> Result<()> { + let len = u32::try_from(len).map_err(|_| Error::LengthOverflow)?; + self.primitive(len.to_le_bytes()) + } +} + +impl ser::Serializer for &mut Serializer { + type Ok = (); + type Error = Error; + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = ser::Impossible<(), Error>; + type SerializeMap = ser::Impossible<(), Error>; + type SerializeStruct = Self; + type SerializeStructVariant = ser::Impossible<(), Error>; + + fn serialize_bool(self, v: bool) -> Result<()> { + self.write(&[u8::from(v)]) + } + + fn serialize_i8(self, v: i8) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_i16(self, v: i16) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_i32(self, v: i32) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_i64(self, v: i64) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_u8(self, v: u8) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_u16(self, v: u16) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_u32(self, v: u32) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_u64(self, v: u64) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_f32(self, v: f32) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_f64(self, v: f64) -> Result<()> { + self.primitive(v.to_le_bytes()) + } + + fn serialize_char(self, _v: char) -> Result<()> { + Err(Error::Unsupported("char")) + } + + fn serialize_str(self, v: &str) -> Result<()> { + self.length(v.len() + 1)?; + self.write(v.as_bytes())?; + self.write(&[0]) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + self.length(v.len())?; + self.write(v) + } + + fn serialize_none(self) -> Result<()> { + Err(Error::Unsupported("Option")) + } + + fn serialize_some(self, _value: &T) -> Result<()> { + Err(Error::Unsupported("Option")) + } + + fn serialize_unit(self) -> Result<()> { + Ok(()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Ok(()) + } + + fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> { + Err(Error::Unsupported("enum")) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T, + ) -> Result<()> { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: &T, + ) -> Result<()> { + Err(Error::Unsupported("enum")) + } + + fn serialize_seq(self, len: Option) -> Result { + self.length(len.ok_or(Error::UnknownLength)?)?; + Ok(self) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Ok(self) + } + + fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(self) + } + + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { + Err(Error::Unsupported("enum")) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(Error::Unsupported("map")) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(self) + } + + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { + Err(Error::Unsupported("enum")) + } + + fn collect_str(self, _value: &T) -> Result<()> { + Err(Error::Unsupported("Display value")) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +impl ser::SerializeSeq for &mut Serializer { + type Ok = (); + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> { + value.serialize(&mut **self) + } + + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl ser::SerializeTuple for &mut Serializer { + type Ok = (); + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> { + value.serialize(&mut **self) + } + + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl ser::SerializeTupleStruct for &mut Serializer { + type Ok = (); + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> { + value.serialize(&mut **self) + } + + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl ser::SerializeStruct for &mut Serializer { + type Ok = (); + type Error = Error; + + fn serialize_field( + &mut self, + _key: &'static str, + value: &T, + ) -> Result<()> { + value.serialize(&mut **self) + } + + fn end(self) -> Result<()> { + Ok(()) + } +} diff --git a/aimdb-cdr/tests/common/mod.rs b/aimdb-cdr/tests/common/mod.rs new file mode 100644 index 00000000..c0864667 --- /dev/null +++ b/aimdb-cdr/tests/common/mod.rs @@ -0,0 +1,113 @@ +//! Shared fixtures. Golden bytes are laid out by hand from the XCDR1 rules. + +#![allow(dead_code)] + +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Mixed { + pub a: u8, + pub b: u32, + pub c: u16, + pub d: f64, + pub s: String, + pub v: Vec, + pub arr: [u8; 3], + pub flag: bool, +} + +pub fn mixed() -> Mixed { + Mixed { + a: 0x11, + b: 0x2233_4455, + c: 0x6677, + d: 1.0, + s: "hi".into(), + v: vec![1, 2], + arr: [7, 8, 9], + flag: true, + } +} + +#[rustfmt::skip] +pub const MIXED_LE: [u8; 48] = [ + 0x00, 0x01, 0x00, 0x00, // CDR_LE header + 0x11, 0, 0, 0, // a, pad to 4 + 0x55, 0x44, 0x33, 0x22, // b + 0x77, 0x66, 0, 0, 0, 0, 0, 0, // c, pad to 8 + 0, 0, 0, 0, 0, 0, 0xf0, 0x3f, // d = 1.0 + 3, 0, 0, 0, b'h', b'i', 0, 0, // s: len incl. NUL, pad + 2, 0, 0, 0, 1, 0, 2, 0, // v: count, elements + 7, 8, 9, // arr: no count + 1, // flag +]; + +#[rustfmt::skip] +pub const MIXED_BE: [u8; 48] = [ + 0x00, 0x00, 0x00, 0x00, // CDR_BE header + 0x11, 0, 0, 0, + 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0, 0, 0, 0, 0, 0, + 0x3f, 0xf0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, b'h', b'i', 0, 0, + 0, 0, 0, 2, 0, 1, 0, 2, + 7, 8, 9, + 1, +]; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Time { + pub sec: i32, + pub nanosec: u32, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Header { + pub stamp: Time, + pub frame_id: String, +} + +/// `sensor_msgs/msg/Temperature`. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Temperature { + pub header: Header, + pub temperature: f64, + pub variance: f64, +} + +pub fn temperature() -> Temperature { + Temperature { + header: Header { + stamp: Time { sec: 1, nanosec: 2 }, + frame_id: "a".into(), + }, + temperature: 0.5, + variance: 0.0, + } +} + +#[rustfmt::skip] +pub const TEMPERATURE_LE: [u8; 36] = [ + 0x00, 0x01, 0x00, 0x00, + 1, 0, 0, 0, // stamp.sec + 2, 0, 0, 0, // stamp.nanosec + 2, 0, 0, 0, b'a', 0, 0, 0, // frame_id, pad to 8 + 0, 0, 0, 0, 0, 0, 0xe0, 0x3f, // temperature = 0.5 + 0, 0, 0, 0, 0, 0, 0, 0, // variance +]; + +/// Tiny xorshift PRNG so the randomized tests need no extra dependency. +pub struct Rng(pub u64); + +impl Rng { + pub fn next(&mut self) -> u64 { + self.0 ^= self.0 << 13; + self.0 ^= self.0 >> 7; + self.0 ^= self.0 << 17; + self.0 + } + + pub fn below(&mut self, n: u64) -> u64 { + self.next() % n + } +} diff --git a/aimdb-cdr/tests/golden.rs b/aimdb-cdr/tests/golden.rs new file mode 100644 index 00000000..05a376f4 --- /dev/null +++ b/aimdb-cdr/tests/golden.rs @@ -0,0 +1,121 @@ +#![cfg(feature = "alloc")] + +mod common; + +use aimdb_cdr::{from_bytes, to_slice, to_vec, Error}; +use common::*; +use serde::{Deserialize, Serialize}; + +#[test] +fn encodes_golden_little_endian() { + assert_eq!(to_vec(&mixed()).unwrap(), MIXED_LE); + assert_eq!(to_vec(&temperature()).unwrap(), TEMPERATURE_LE); +} + +#[test] +fn decodes_both_byte_orders() { + assert_eq!(from_bytes::(&MIXED_LE).unwrap(), mixed()); + assert_eq!(from_bytes::(&MIXED_BE).unwrap(), mixed()); + assert_eq!( + from_bytes::(&TEMPERATURE_LE).unwrap(), + temperature() + ); +} + +#[test] +fn to_slice_matches_to_vec_and_reports_small_buffers() { + let mut out = [0u8; 48]; + assert_eq!(to_slice(&mixed(), &mut out), Ok(48)); + assert_eq!(out, MIXED_LE); + + let mut short = [0u8; 47]; + assert_eq!(to_slice(&mixed(), &mut short), Err(Error::BufferTooSmall)); + assert_eq!( + to_slice(&mixed(), &mut [0u8; 3]), + Err(Error::BufferTooSmall) + ); +} + +#[test] +fn empty_string_and_sequence() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Empty { + s: String, + v: Vec, + } + let value = Empty { + s: String::new(), + v: Vec::new(), + }; + let bytes = to_vec(&value).unwrap(); + assert_eq!(bytes, [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + assert_eq!(from_bytes::(&bytes).unwrap(), value); +} + +#[test] +fn nested_sequences_of_structs() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Path { + poses: Vec