diff --git a/Cargo.lock b/Cargo.lock index 689646e..af212f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,6 +341,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -417,6 +426,20 @@ name = "bytemuck" version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] [[package]] name = "byteorder" @@ -2112,9 +2135,9 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" +checksum = "8b8c72594ac26bfd34f2d99dfced2edfaddfe8a476e3ff2ca0eb293d925c4f83" dependencies = [ "twox-hash", ] @@ -2610,6 +2633,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -3123,6 +3156,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rcgen" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57f6d249aad744e274e682777a50283a225a32705394ee6d5fcc01efa25e4055" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "x509-parser", + "yasna", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -3322,7 +3369,7 @@ dependencies = [ [[package]] name = "ros-z" version = "0.1.0" -source = "git+https://github.com/ZettaScaleLabs/ros-z.git#e4fdecc8dac71977093ce5ed666dab852789eb1a" +source = "git+https://github.com/ZettaScaleLabs/ros-z.git?rev=9bb6305#9bb63050e74ff0a27559534255f0508a19491d08" dependencies = [ "byteorder", "clap", @@ -3334,8 +3381,12 @@ dependencies = [ "parking_lot", "paste", "ros-z-cdr", + "ros-z-derive", + "ros-z-protocol", + "ros-z-schema", "serde", "serde_json", + "serde_yaml", "sha2", "slab", "strum", @@ -3351,14 +3402,44 @@ dependencies = [ [[package]] name = "ros-z-cdr" version = "0.1.0" -source = "git+https://github.com/ZettaScaleLabs/ros-z.git#e4fdecc8dac71977093ce5ed666dab852789eb1a" +source = "git+https://github.com/ZettaScaleLabs/ros-z.git?rev=9bb6305#9bb63050e74ff0a27559534255f0508a19491d08" dependencies = [ + "bytemuck", "byteorder", "serde", "thiserror 1.0.69", "zenoh-buffers", ] +[[package]] +name = "ros-z-derive" +version = "0.1.0" +source = "git+https://github.com/ZettaScaleLabs/ros-z.git?rev=9bb6305#9bb63050e74ff0a27559534255f0508a19491d08" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ros-z-protocol" +version = "0.1.0" +source = "git+https://github.com/ZettaScaleLabs/ros-z.git?rev=9bb6305#9bb63050e74ff0a27559534255f0508a19491d08" +dependencies = [ + "zenoh", +] + +[[package]] +name = "ros-z-schema" +version = "0.1.0" +source = "git+https://github.com/ZettaScaleLabs/ros-z.git?rev=9bb6305#9bb63050e74ff0a27559534255f0508a19491d08" +dependencies = [ + "hex", + "serde", + "serde_json", + "sha2", +] + [[package]] name = "roslibrust" version = "0.20.0" @@ -3987,6 +4068,15 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4798,6 +4888,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.13.0", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow 0.7.14", +] + [[package]] name = "toml_datetime" version = "0.7.5+spec-1.1.0" @@ -4816,18 +4921,24 @@ dependencies = [ "indexmap 2.13.0", "toml_datetime", "toml_parser", - "winnow", + "winnow 0.7.14", ] [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.3", ] +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tower-service" version = "0.3.3" @@ -4975,9 +5086,13 @@ dependencies = [ [[package]] name = "twox-hash" -version = "2.1.2" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] [[package]] name = "typeid" @@ -5337,7 +5452,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -5745,6 +5860,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" + [[package]] name = "winreg" version = "0.50.0" @@ -5779,6 +5900,7 @@ dependencies = [ "lazy_static", "nom 7.1.3", "oid-registry", + "ring", "rusticata-macros", "thiserror 2.0.18", "time", @@ -5790,6 +5912,16 @@ version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" +[[package]] +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" @@ -5828,9 +5960,9 @@ dependencies = [ [[package]] name = "zenoh" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9ff8cb89f5267b8486a69466bc42f240f1ee2d5089e72395a23094e7b74f21" +checksum = "85e22d7002ac149ef17fe400bb40a267ebbba40a83413bab03da7762256fa94e" dependencies = [ "ahash", "arc-swap", @@ -5849,7 +5981,6 @@ dependencies = [ "petgraph", "phf", "rand 0.8.5", - "ref-cast", "rustc_version", "serde", "serde_json", @@ -5881,18 +6012,18 @@ dependencies = [ [[package]] name = "zenoh-buffers" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9216c3d6c84b56f3e3be634e52365022038e1ac1b9f662f10d425cbf6c0fa8" +checksum = "e89c9e2427102e8efd533716f0935389a3900a818e7334004dd647ac0bd029dc" dependencies = [ "zenoh-collections", ] [[package]] name = "zenoh-codec" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14bc6747664aa9ecf17becd6e9a29282e535a350cd7c6bd8de7bf2dc662fb93d" +checksum = "31930531a8e387160bc3680c6d62f80a201020cf4d8aa36bd46988b425a66306" dependencies = [ "tracing", "uhlc", @@ -5903,18 +6034,18 @@ dependencies = [ [[package]] name = "zenoh-collections" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d642ecfe0d85f0cd846be9bc92805d926c092a6e6c7a575b6346752f8c3ae16" +checksum = "6fc5195efe3ad44786275f559bbd6f13c6612470e9706c9a9a8b5b47388d51e1" dependencies = [ "ahash", ] [[package]] name = "zenoh-config" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39765a5f9975aba204c99f2f65308db4952dbea8e5ac79c78ac1eaf5711e970a" +checksum = "e8672f4eaf88fd486f0503c59d19edfc25e7dd689bccd90d3cb731a5f627e0df" dependencies = [ "json5", "nonempty-collections", @@ -5924,6 +6055,7 @@ dependencies = [ "serde_json", "serde_with", "serde_yaml", + "toml", "tracing", "uhlc", "validated_struct", @@ -5937,9 +6069,9 @@ dependencies = [ [[package]] name = "zenoh-core" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c0c1388dccf287aec4e9d5e638630dc9d536db9f1da3522889b42697723b9b" +checksum = "1525319e4d9ef2af54fc9c74abf419236e32e6535081339321f3f55e2f34ce2f" dependencies = [ "lazy_static", "tokio", @@ -5949,9 +6081,9 @@ dependencies = [ [[package]] name = "zenoh-crypto" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b433e08df3b03f2af2d23bd29a32aa5f5522c52e66d63e3d135bfa66373736dd" +checksum = "44b80a042fc71419fc4952a90c9cbcfb323c0ced048125d8b44fd362f184045f" dependencies = [ "aes", "hmac", @@ -5963,9 +6095,9 @@ dependencies = [ [[package]] name = "zenoh-ext" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fddc96d0b206af968465ca8497cd2f8bab9639bb028391f354b057fc9a1d6b0" +checksum = "4e4de171bff459816b1ca9e6657c4ae9783d2c1fc569e1721a380521425e897d" dependencies = [ "async-trait", "bincode", @@ -5983,9 +6115,9 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a3c47c89cb55ea45a1b3fe7d1fe8682ea93530b1fc5245257812db14b55b3d" +checksum = "80f04c82f0728f6704a1a397a04b38de5b2fd5a9a886a232cf650c9af294ba5d" dependencies = [ "getrandom 0.2.17", "hashbrown 0.16.1", @@ -5999,9 +6131,9 @@ dependencies = [ [[package]] name = "zenoh-link" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6218cecab58435f31fb8b2e185f74f35af8aedd96e8bdd3557b333206b1acfda" +checksum = "a71103cfe96a851ef5ff781d64dda95c70e70208f74e186d6d294ba21e89cc64" dependencies = [ "zenoh-config", "zenoh-link-commons", @@ -6019,15 +6151,18 @@ dependencies = [ [[package]] name = "zenoh-link-commons" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98adc618f7edb570b9333ce583934a7c63e3a619cb49666515bfc06a000d7b6" +checksum = "8dc91a5163793f842b4b016b2d50640db5a3533370348eb796e7078c576e87cf" dependencies = [ "async-trait", "base64 0.22.1", + "bytes", "flume", "futures", "quinn", + "quinn-proto", + "rcgen", "rustls", "rustls-pemfile 2.2.0", "rustls-pki-types", @@ -6053,56 +6188,43 @@ dependencies = [ [[package]] name = "zenoh-link-quic" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0c25d681db958b7714370d5e1d72a523129633d9262b098e18d44824d39893" +checksum = "17d065833147be895b7091cc3e505433c2c8b3172e36c9e06e84a5779a4aa655" dependencies = [ "async-trait", - "base64 0.22.1", - "quinn", - "rustls", - "rustls-pemfile 2.2.0", "rustls-webpki", - "secrecy", "time", - "tokio", - "tokio-util", "tracing", - "webpki-roots 1.0.5", - "zenoh-config", "zenoh-core", "zenoh-link-commons", + "zenoh-link-quic_datagram", "zenoh-protocol", "zenoh-result", - "zenoh-util", ] [[package]] name = "zenoh-link-quic_datagram" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb427adbc8d367505b9a62a6614c9d7802e420f03466d98644bb7bf24516f" +checksum = "e81b15df31a3d0ddde9a4fb3fbc928e9a2a6d6a4de38bcf55badd3a5208947a4" dependencies = [ "async-trait", - "quinn", - "rustls", "rustls-webpki", "time", - "tokio", "tokio-util", "tracing", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", - "zenoh-util", ] [[package]] name = "zenoh-link-serial" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee91f2e7f7ea44e10e3cdffcda728fcbfcd1d1f9111420164dbfab4c3872c28" +checksum = "7f46b4d7bb81c60aff1ab7c54c5bd1d63a8a7987112bf3b579b468069cd4bbb3" dependencies = [ "async-trait", "tokio", @@ -6119,9 +6241,9 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f23bd5d06a0014ce5a205961d6d47c8e8d792d9fd050ae9d0c9b609a187995" +checksum = "4e912ac36902173dfc295317e001dc630e5ac9a70c2780f2d2eac500b205a700" dependencies = [ "async-trait", "socket2 0.5.10", @@ -6137,9 +6259,9 @@ dependencies = [ [[package]] name = "zenoh-link-tls" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17544cde682dbcd2a712114786feee14295c28a9f66fc1021637355511e32fa9" +checksum = "e6f6b308ae2599f9c1344fbcd3418b2c3a3a9fe287ec39501ba834168493ba37" dependencies = [ "async-trait", "base64 0.22.1", @@ -6167,9 +6289,9 @@ dependencies = [ [[package]] name = "zenoh-link-udp" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "587ca1de1caa0b444106d31c26801f4e87b354293d2d37afd8f70d9e793fe35e" +checksum = "ca106ca8c3b7625e7071b9d7408955726e994c8f35fd68e00de8ac58b185d52d" dependencies = [ "async-trait", "libc", @@ -6181,6 +6303,7 @@ dependencies = [ "zenoh-buffers", "zenoh-core", "zenoh-link-commons", + "zenoh-link-quic_datagram", "zenoh-protocol", "zenoh-result", "zenoh-sync", @@ -6189,9 +6312,9 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac46470a17af5861e07ed9d2440277e7a3dea55109b0988866b635f7daf29ac4" +checksum = "09f2b7f60cdb5ad771d1a4f8e2eda15529e96dbe81c0ad2c1015b4c194347676" dependencies = [ "async-trait", "nix 0.29.0", @@ -6208,9 +6331,9 @@ dependencies = [ [[package]] name = "zenoh-link-ws" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4be09c3e32d510cdddf3289bc333d53471883198fca51d58248458a20df3d51" +checksum = "9a7fb54899f7fbdfc4fd02e647f9bba0d6e089cca4355acafb9499c510ebea79" dependencies = [ "async-trait", "futures-util", @@ -6229,9 +6352,9 @@ dependencies = [ [[package]] name = "zenoh-macros" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b760a458cd906ac888b37fd1abdb21a0f58ecc64cc3882f83a976cb5ca8e0632" +checksum = "9310b02a8f6dc4bd04d9ce6b318b9d00182aeeeeca60410003307d63a2569a3f" dependencies = [ "proc-macro2", "quote", @@ -6241,9 +6364,9 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7325b773c43a86a94f800cb971ab7e4b7e01ce76819c9c100ea783a47c3a25e4" +checksum = "e235815d14b22448aa1db948560328761530932fa7a2f9a3c14853b3f0267941" dependencies = [ "git-version", "libloading", @@ -6259,9 +6382,9 @@ dependencies = [ [[package]] name = "zenoh-protocol" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4d3dad7aeeea780495692b195cd56515569c32b76b9dd077cc408c3ebca03f" +checksum = "eeab45020bbecc077f14f06ee8f5aee65ce760af72481e663cac58b5dbfa66dd" dependencies = [ "const_format", "rand 0.8.5", @@ -6269,23 +6392,24 @@ dependencies = [ "uhlc", "zenoh-buffers", "zenoh-keyexpr", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-result" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b4dbfea68b947a790d5525bcf061e91e2fdc2798bce619851919b353a8580fa" +checksum = "cca8e65b08f211833fe31cf38d73a48c6e1d6d900914e1ddd8cb176b3355b75b" dependencies = [ "anyhow", ] [[package]] name = "zenoh-runtime" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760a1f7880f98427ad849d600257d1455a18afe981681f362684a3f91042537e" +checksum = "dd3d0c1558f909c9a74bde5e398c5733f81eb954818451baac2a6c09f48d6a5e" dependencies = [ "lazy_static", "ron", @@ -6298,9 +6422,9 @@ dependencies = [ [[package]] name = "zenoh-shm" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42184ae820d64d40814c0dd3b48f748c55a3ff5591c524f1bde36f21ccfda488" +checksum = "a63670c8845775b21f718401a317c7824c604915fec6d228570456bb919994e7" dependencies = [ "advisory-lock", "async-trait", @@ -6328,9 +6452,9 @@ dependencies = [ [[package]] name = "zenoh-stats" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8954c79580ed3365580d86f40657f2cd6bf4b4c72dd463de936368df8c709c65" +checksum = "e2bd56586221cca3cbb75b8bfe6f9451219a9241b0a49228b498467705d7e10d" dependencies = [ "ahash", "prometheus-client", @@ -6342,9 +6466,9 @@ dependencies = [ [[package]] name = "zenoh-sync" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f132137bb003f10b7fff086cb18addf8e8273b9c0d2722a53b5074c8a79965" +checksum = "9588f87db82b414a3e73d13312026be826332f53d270966e3e19f77f7fa1f06d" dependencies = [ "arc-swap", "event-listener", @@ -6357,9 +6481,9 @@ dependencies = [ [[package]] name = "zenoh-task" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b17d10136fdabec7e21a3fcef568c210ee6a2d71cde6adcde99e9236584f3a1" +checksum = "1e2ac601598a27152b366ba1c6825216f01f77bb898f719b7752099a3594ce72" dependencies = [ "futures", "tokio", @@ -6371,13 +6495,14 @@ dependencies = [ [[package]] name = "zenoh-transport" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50739b4c45e0963df8377abddb74701a4b708b178590eae92f27a604e25daf44" +checksum = "80800c4adc26dbe81418735068541cf39820a95ec988114f04dd014775ba7c97" dependencies = [ "async-trait", "crossbeam-utils", "flume", + "futures", "lazy_static", "lz4_flex", "rand 0.8.5", @@ -6407,9 +6532,9 @@ dependencies = [ [[package]] name = "zenoh-util" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9512987c13925d32d3331507c8807853d5b682ea8da94d0ba6534c7a8ace48aa" +checksum = "1b10369df18a781a3e675c9a2cbf54adb44c9dc2a376c1014c5e488410df2179" dependencies = [ "async-trait", "const_format", diff --git a/roslibrust_ros2/Cargo.toml b/roslibrust_ros2/Cargo.toml index c7d2cb0..0c4f8fe 100644 --- a/roslibrust_ros2/Cargo.toml +++ b/roslibrust_ros2/Cargo.toml @@ -12,8 +12,8 @@ env_logger = "0.11" cdr = "0.2" roslibrust_common = { path = "../roslibrust_common", version = "0.20" } anyhow = "1.0" -# Experimental "raw ros" library, we're going to try to build on top of -ros-z = { git = "https://github.com/ZettaScaleLabs/ros-z.git" } +# Main as of May 16th 2026 +ros-z = { git = "https://github.com/ZettaScaleLabs/ros-z.git", rev = "9bb6305" } log = "0.4" # Used for cancellation token tokio-util = "0.7" diff --git a/roslibrust_ros2/src/lib.rs b/roslibrust_ros2/src/lib.rs index 48019c3..4b7277c 100644 --- a/roslibrust_ros2/src/lib.rs +++ b/roslibrust_ros2/src/lib.rs @@ -5,123 +5,71 @@ use std::result::Result as StdResult; use ros_z::{ context::ZContext, entity::{TypeHash, TypeInfo}, - msg::ZService, + msg::{SerdeCdrSerdes, ZMessage, ZService}, pubsub::{ZPub, ZSub}, - ros_msg::{ServiceTypeInfo, WithTypeInfo}, + ros_msg::ServiceTypeInfo, Builder, }; /// re-export ros_z for consumers pub use ros_z; -/// Wrapper type that implements WithTypeInfo for RosMessageType -/// This allows RosMessageType implementations to work with ros-z's type system -pub struct RosMessageWrapper(pub T); - -impl ros_z::ros_msg::MessageTypeInfo for RosMessageWrapper { - fn type_name() -> &'static str { - T::ROS2_TYPE_NAME - } - - fn type_hash() -> TypeHash { - TypeHash::new(1, *T::ROS2_HASH) - } +/// A "newtype" wrapper around ZNode so we can implement roslibrust's traits for it. +pub struct ZenohClient { + node: ros_z::node::ZNode, } -impl WithTypeInfo for RosMessageWrapper {} - -// Custom serializer that treats RosMessageWrapper as T for serialization purposes -pub struct WrapperSerdes(std::marker::PhantomData); - -impl ros_z::msg::ZSerializer for WrapperSerdes { - type Input<'a> = &'a RosMessageWrapper; - fn serialize(input: Self::Input<'_>) -> Vec { - ros_z::msg::CdrSerdes::::serialize(&input.0) - } - - fn serialize_to_zbuf(input: Self::Input<'_>) -> zenoh_buffers::ZBuf { - ros_z::msg::CdrSerdes::::serialize_to_zbuf(&input.0) - } - - fn serialize_to_buf(input: Self::Input<'_>, buffer: &mut Vec) { - ros_z::msg::CdrSerdes::::serialize_to_buf(&input.0, buffer) - } +type RosZSerdes = SerdeCdrSerdes>; - fn serialize_to_zbuf_with_hint( - input: Self::Input<'_>, - capacity_hint: usize, - ) -> zenoh_buffers::ZBuf { - ros_z::msg::CdrSerdes::::serialize_to_zbuf_with_hint(&input.0, capacity_hint) - } +struct RosZMessage(T); - fn serialize_to_shm( - input: Self::Input<'_>, - estimated_size: usize, - provider: &zenoh::shm::ShmProvider, - ) -> zenoh::Result<(zenoh_buffers::ZBuf, usize)> { - ros_z::msg::CdrSerdes::::serialize_to_shm(&input.0, estimated_size, provider) - } +impl ZMessage for RosZMessage { + type Serdes = RosZSerdes; } -impl ros_z::msg::ZDeserializer for WrapperSerdes { - type Input<'a> = &'a [u8]; - type Output = RosMessageWrapper; - type Error = ros_z::msg::CdrError; - fn deserialize(data: Self::Input<'_>) -> std::result::Result { - let inner = ros_z::msg::CdrSerdes::::deserialize(data)?; - Ok(RosMessageWrapper(inner)) +impl serde::Serialize for RosZMessage { + fn serialize(&self, serializer: S) -> StdResult { + self.0.serialize(serializer) } } -impl ros_z::msg::ZMessage for RosMessageWrapper { - type Serdes = WrapperSerdes; -} - -/// A "newtype" wrapper around ZNode so we can implement roslibrust's traits for it. -pub struct ZenohClient { - // TODO: We'll probably end up wrapping node in an Arc<> so we can make this clone for users - node: ros_z::node::ZNode, +impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for RosZMessage { + fn deserialize>(deserializer: D) -> StdResult { + T::deserialize(deserializer).map(Self) + } } -// A "newtype" wrapper around ZPub so we can implement roslibrust's traits for it. /// The publisher type returned by [TopicProvider::advertise] on [ZenohClient]. -/// This type is self de-registering, and dropping the publisher will automatically un-advertise the topic. -/// This type is generic on the message type that will be published. pub struct ZenohPublisher { - publisher: ZPub, WrapperSerdes>, - _marker: std::marker::PhantomData, + publisher: ZPub, RosZSerdes>, } impl Publish for ZenohPublisher { async fn publish(&self, data: &T) -> Result<()> { + let data = RosZMessage(data.clone()); self.publisher - .async_publish(&RosMessageWrapper(data.clone())) + .async_publish(&data) .await - // TODO: should work on error type here with ros_z team .map_err(|e| Error::Unexpected(anyhow::anyhow!(e))) } } /// The subscriber type returned by [TopicProvider::subscribe] on [ZenohClient]. -/// This type is self de-registering, and dropping the subscriber will automatically unsubscribe from the topic. -/// This type is generic on the message type that will be received. -/// It is typically used with types generated by roslibrust's codegen. pub struct ZenohSubscriber { - subscriber: ZSub, zenoh::sample::Sample, WrapperSerdes>, - _marker: std::marker::PhantomData, + subscriber: ZSub, zenoh::sample::Sample, RosZSerdes>, } impl Subscribe for ZenohSubscriber { async fn next(&mut self) -> Result { - let next = self.subscriber.async_recv().await; - let msg = next.map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; - Ok(msg.0) + self.subscriber + .async_recv() + .await + .map(|msg| msg.0) + .map_err(|e| Error::Unexpected(anyhow::anyhow!(e))) } } impl ZenohClient { - // TODO don't love error type here... could work with ros_z to get better errors - /// Creates a new node with the specified name and return a handle to it. pub async fn new( ctx: &ZContext, name: impl AsRef, @@ -131,6 +79,11 @@ impl ZenohClient { } } +/// Build a TypeInfo from a RosMessageType's type name and hash. +fn ros_type_info() -> TypeInfo { + TypeInfo::new(T::ROS2_TYPE_NAME, TypeHash::new(1, *T::ROS2_HASH)) +} + impl roslibrust_common::TopicProvider for ZenohClient { type Publisher = ZenohPublisher; type Subscriber = ZenohSubscriber; @@ -142,16 +95,14 @@ impl roslibrust_common::TopicProvider for ZenohClient { let topic: roslibrust_common::GlobalTopicName = topic.to_global_name()?; let publisher = self .node - .create_pub::>(topic.as_ref()) - .with_serdes::>() + .create_pub_impl::>( + topic.as_ref(), + Some(ros_type_info::()), + ) .build() - // TODO better errors .map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; - Ok(ZenohPublisher { - publisher, - _marker: std::marker::PhantomData, - }) + Ok(ZenohPublisher { publisher }) } async fn subscribe( @@ -161,23 +112,18 @@ impl roslibrust_common::TopicProvider for ZenohClient { let topic: roslibrust_common::GlobalTopicName = topic.to_global_name()?; let sub = self .node - .create_sub::>(topic.as_ref()) - .with_serdes::>() + .create_sub_impl::>( + topic.as_ref(), + Some(ros_type_info::()), + ) .build() - // TODO better errors .map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; - Ok(ZenohSubscriber { - subscriber: sub, - _marker: std::marker::PhantomData, - }) + Ok(ZenohSubscriber { subscriber: sub }) } } -// TODO MAJOR: problem here ZService trait can't be implemented for our example messages due to orphan rule... -// Have to do some gross work around to get roslibrust::RosServiceType and ros_z::ZService to play nicely together pub struct ZenohServiceServer { - // Used to shutdown server task when dropped cancellation_token: tokio_util::sync::CancellationToken, } @@ -192,11 +138,13 @@ pub struct ZenohServiceClient { _marker: std::marker::PhantomData, } -// Helper struct to work around orphan rule +// Orphan-rule shim: ZService (ros_z) cannot be impl'd for T: RosServiceType (roslibrust_common) +// in a downstream crate. This unit struct bridges the two. struct Fake(std::marker::PhantomData); + impl ZService for Fake { - type Request = T::Request; - type Response = T::Response; + type Request = RosZMessage; + type Response = RosZMessage; } impl ServiceTypeInfo for Fake { @@ -207,19 +155,12 @@ impl ServiceTypeInfo for Fake { impl roslibrust_common::Service for ZenohServiceClient { async fn call(&self, request: &T::Request) -> Result { - // Send the request + let request = RosZMessage(request.clone()); self.client - .send_request(request) + .call(&request) .await - .map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; - - // Wait for and take the response - let response = self - .client - .take_response() - .map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; - - Ok(response) + .map(|response| response.0) + .map_err(|e| Error::Unexpected(anyhow::anyhow!(e))) } } @@ -233,7 +174,6 @@ impl roslibrust_common::ServiceProvider for ZenohClient { request: SrvType::Request, ) -> Result { let service: roslibrust_common::GlobalTopicName = service.to_global_name()?; - // Create a service client and call it once let client = ZenohClient::service_client::(self, service.as_ref()).await?; client.call(&request).await } @@ -261,17 +201,6 @@ impl roslibrust_common::ServiceProvider for ZenohClient { server: F, ) -> Result { let service: roslibrust_common::GlobalTopicName = service.to_global_name()?; - // TODO: doing some really dome stuff here... to work around orphan rule and RosServiceType != ZService - struct Fake(T); - impl ZService for Fake { - type Request = T::Request; - type Response = T::Response; - } - impl ServiceTypeInfo for Fake { - fn service_type_info() -> TypeInfo { - TypeInfo::new(T::ROS2_TYPE_NAME, TypeHash::new(1, *T::ROS2_HASH)) - } - } let mut svc = self .node @@ -280,16 +209,15 @@ impl roslibrust_common::ServiceProvider for ZenohClient { .map_err(|e| Error::Unexpected(anyhow::anyhow!(e)))?; let cancellation_token = tokio_util::sync::CancellationToken::new(); - - // Build a clone wrapper for the users's function let server = std::sync::Arc::new(server); let service_name = String::from(service); let ct_copy = cancellation_token.clone(); + tokio::spawn(async move { let body_future = async { loop { - let req = svc.take_request_async().await; - let (query, req) = match req { + let req = svc.async_take_request().await; + let req = match req { Ok(req) => req, Err(e) => { error!("Failed to take request in service {service_name}: {e:?}"); @@ -298,12 +226,12 @@ impl roslibrust_common::ServiceProvider for ZenohClient { }; debug!( "Got request for service {service_name} with key {:?}", - query + req.id() ); - // Evaluate the server function inside a spawn_blocking to uphold trait expectations from roslibrust_common + let (req, reply) = req.into_parts(); let server_copy = server.clone(); - let response = tokio::task::spawn_blocking(move || server_copy(req)).await; + let response = tokio::task::spawn_blocking(move || server_copy(req.0)).await; let valid_response = match response { Ok(Ok(response)) => response, @@ -316,20 +244,17 @@ impl roslibrust_common::ServiceProvider for ZenohClient { continue; } }; - let send_result = svc.send_response_async(&valid_response, &query).await; - match send_result { - Ok(()) => {} - Err(e) => { - error!("Failed to send response to service {service_name}: {e:?}"); - } - }; + + let valid_response = RosZMessage(valid_response); + let send_result = reply.reply(&valid_response).await; + if let Err(e) = send_result { + error!("Failed to send response to service {service_name}: {e:?}"); + } } }; tokio::select! { - _ = ct_copy.cancelled() => { - // Shutdown - } + _ = ct_copy.cancelled() => {} _ = body_future => { error!("Service task for {service_name} exited unexpectedly"); } @@ -360,7 +285,6 @@ mod tests { .unwrap() } - // Ignored for now until we get ROS2 zenoh CI stable #[ignore] #[tokio::test(flavor = "multi_thread")] async fn test_subscribe_basic() { @@ -377,7 +301,6 @@ mod tests { let mut pub_cmd = std::process::Command::new("ros2") .arg("topic") .arg("pub") - // Publish 10 times .arg("-t") .arg("10") .arg("/chatter") @@ -427,7 +350,6 @@ mod tests { .expect("Failed to receive message within 2 seconds"); } - // Test is currently failing... Want to merge this code and then file issues to gradually fix #[ignore] #[tokio::test(flavor = "multi_thread")] async fn test_service_server_callable() { @@ -437,7 +359,6 @@ mod tests { .unwrap(); let state = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); - let state_copy = state.clone(); let server_fn = move |request: roslibrust_test::ros2::std_srvs::SetBoolRequest| { state_copy.store(request.data, std::sync::atomic::Ordering::SeqCst); @@ -473,13 +394,9 @@ mod tests { .await .expect("Bool should be set true within 2 seconds"); - // If we reach here, state was changed to true by the service call! - - // Protection to make sure we don't leave a ros2 service call running srv_call_cmd.kill().unwrap() } - // Test disabled on Jan 21 '25, waiting for ros-z development to stabilize #[ignore] #[tokio::test(flavor = "multi_thread")] async fn test_service_zenoh_to_zenoh() { @@ -499,7 +416,6 @@ mod tests { }) }; - // NOTE: Cannot use multi-part names for services in ros2 currently let _service = node .advertise_service::( "/test_service_zenoh_to_zenoh_set_bool", @@ -508,10 +424,8 @@ mod tests { .await .unwrap(); - // Give server time to start tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; - // Create service client and call the service let response = node .call_service::( "/test_service_zenoh_to_zenoh_set_bool", @@ -520,11 +434,8 @@ mod tests { .await .expect("Service call should succeed"); - // Verify the response assert!(response.success); assert_eq!(response.message, "You set my bool!"); - - // Verify the server state was updated assert!(state.load(std::sync::atomic::Ordering::SeqCst)); } }