zbus-lockstep-0.5.1/.cargo_vcs_info.json0000644000000001530000000000100136430ustar { "git": { "sha1": "1b09377f5a838158f9befac4c079893af8b3ce35" }, "path_in_vcs": "zbus-lockstep" }zbus-lockstep-0.5.1/Cargo.lock0000644000000555110000000000100116260ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "cfg-if" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "endi" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] name = "enumflags2" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", "serde", ] [[package]] name = "enumflags2_derive" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", "windows-sys 0.60.2", ] [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "form_urlencoded" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "getrandom" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", "r-efi", "wasi", ] [[package]] name = "hashbrown" version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "icu_collections" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] name = "icu_locale_core" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", "tinystr", "writeable", "zerovec", ] [[package]] name = "icu_normalizer" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", "zerovec", ] [[package]] name = "icu_normalizer_data" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", "zerotrie", "zerovec", ] [[package]] name = "idna" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ "idna_adapter", "smallvec", "utf8_iter", ] [[package]] name = "idna_adapter" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", ] [[package]] name = "indexmap" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "linux-raw-sys" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "memchr" version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "potential_utf" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" dependencies = [ "zerovec", ] [[package]] name = "proc-macro-crate" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit 0.22.27", ] [[package]] name = "proc-macro2" version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "pulldown-cmark" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ "bitflags", "memchr", "unicase", ] [[package]] name = "quick-xml" version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" dependencies = [ "memchr", "serde", ] [[package]] name = "quote" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.59.0", ] [[package]] name = "semver" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_spanned" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "synstructure" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "tempfile" version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", ] [[package]] name = "tinystr" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", ] [[package]] name = "toml" version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", "toml_datetime", "toml_edit 0.19.15", ] [[package]] name = "toml_datetime" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "toml_datetime", "winnow 0.7.11", ] [[package]] name = "unicase" version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "url" version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "version-sync" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835169da0173ea373ddf5987632aac1f918967fbbe58195e304342282efa6089" dependencies = [ "proc-macro2", "pulldown-cmark", "regex", "semver", "syn", "toml", "url", ] [[package]] name = "wasi" version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets 0.53.2", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows-targets" version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", "windows_i686_gnullvm 0.53.0", "windows_i686_msvc 0.53.0", "windows_x86_64_gnu 0.53.0", "windows_x86_64_gnullvm 0.53.0", "windows_x86_64_msvc 0.53.0", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] [[package]] name = "writeable" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", "yoke-derive", "zerofrom", ] [[package]] name = "yoke-derive" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zbus-lockstep" version = "0.5.1" dependencies = [ "tempfile", "version-sync", "zbus_xml", "zvariant", ] [[package]] name = "zbus_names" version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", "winnow 0.7.11", "zvariant", ] [[package]] name = "zbus_xml" version = "5.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589e9a02bfafb9754bb2340a9e3b38f389772684c63d9637e76b1870377bec29" dependencies = [ "quick-xml", "serde", "static_assertions", "zbus_names", "zvariant", ] [[package]] name = "zerofrom" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", "syn", "synstructure", ] [[package]] name = "zerotrie" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" dependencies = [ "displaydoc", "yoke", "zerofrom", ] [[package]] name = "zerovec" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", "zerovec-derive", ] [[package]] name = "zerovec-derive" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zvariant" version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" dependencies = [ "endi", "enumflags2", "serde", "winnow 0.7.11", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", "zvariant_utils", ] [[package]] name = "zvariant_utils" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" dependencies = [ "proc-macro2", "quote", "serde", "static_assertions", "syn", "winnow 0.7.11", ] zbus-lockstep-0.5.1/Cargo.toml0000644000000025460000000000100116510ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "zbus-lockstep" version = "0.5.1" authors = [ "Luuk van der Duim ", "Tait Hoyem", ] build = false include = [ "src/**/*", "LICENSE-MIT", "README.md", ] publish = true autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Keep types in lockstep with DBus XML definitions" documentation = "https://docs.rs/zbus-lockstep" readme = "README.md" keywords = [ "type-safety", "zbus", "DBus", "IPC", ] license = "MIT" repository = "https://github.com/luukvanderduim/zbus-lockstep" [badges.maintenance] status = "actively-developed" [lib] name = "zbus_lockstep" path = "src/lib.rs" [dependencies.zbus_xml] version = "5.0.1" [dependencies.zvariant] version = "5.1" [dev-dependencies.tempfile] version = "3" [dev-dependencies.version-sync] version = "0.9" zbus-lockstep-0.5.1/Cargo.toml.orig000064400000000000000000000014171046102023000153260ustar 00000000000000[package] name = "zbus-lockstep" authors = [ "Luuk van der Duim ", "Tait Hoyem", ] description = "Keep types in lockstep with DBus XML definitions" version = "0.5.1" edition = "2021" keywords = ["type-safety", "zbus", "DBus", "IPC"] documentation = "https://docs.rs/zbus-lockstep" repository = "https://github.com/luukvanderduim/zbus-lockstep" readme = "README.md" license = "MIT" include = ["src/**/*", "LICENSE-MIT", "README.md"] publish = true [badges.maintenance] status = "actively-developed" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] zbus_xml = { version = "5.0.1" } zvariant = { version = "5.1" } [dev-dependencies] tempfile = "3" version-sync = "0.9" zbus-lockstep-0.5.1/LICENSE-MIT000064400000000000000000000017771046102023000141040ustar 00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. zbus-lockstep-0.5.1/README.md000064400000000000000000000070401046102023000137140ustar 00000000000000# zbus-lockstep [![CI](https://github.com/luukvanderduim/zbus-lockstep/actions/workflows/rust.yml/badge.svg)](https://github.com/luukvanderduim/zbus-lockstep/actions/workflows/rust.yml) ![Maintenance](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg) [![crates-io](https://img.shields.io/crates/v/zbus-lockstep.svg)](https://crates.io/crates/zbus-lockstep) [![api-docs](https://docs.rs/zbus-lockstep/badge.svg)](https://docs.rs/zbus-lockstep) `zbus-lockstep` helps keep type definitions in lockstep with DBus XML descriptions, using [`zbus-xml`](). It offers means to match your type's signature - [`::signature()`](https://docs.rs/zvariant/latest/zvariant/trait.Type.html#tymethod.signature) - with a corresponding signature retrieved from a DBus XML file. This way `zbus-lockstep` prevents definitions from drifting apart. ## Motivation In the context of IPC over `DBus` - especially when there are multiple implementations of servers and/or clients - it is necessary for each implementation to send what others expect and that expectations are in accordance with what is sent over the bus. The `XML` protocol-descriptions may act as a shared frame of reference or "single source of all truth" for all implementers. Having a single point of reference helps all implementers meet expectations on protocol conformance. Keeping the types you send over `DBus` in lockstep with currently valid protocol-descriptions will reduce chances of miscommunication or failure to communicate. ## Usage Add `zbus-lockstep` to `Cargo.toml`'s dev-dependencies: ```toml [dev-dependencies] zbus-lockstep = "0.5.1" ``` Consider the followwing XML description, an interface with a single signal. ```XML ``` The type in our implementation might look like this: ```rust #[derive(Type)] struct Node { name: String, path: OwnedObjectPath, } ``` The derive macro in this example implements the [`zvariant::Type`](https://docs.rs/zvariant/latest/zvariant/trait.Type.html). This means we can now call `) -> std::fmt::Result { match self { LockstepError::ArgumentNotFound(name) => { write!(f, "Argument \"{name}\" not found.") } LockstepError::InterfaceNotFound(name) => { write!(f, "Interface \"{name}\" not found.") } LockstepError::MemberNotFound(name) => { write!(f, "Member \"{name}\" not found.") } LockstepError::PropertyNotFound(name) => { write!(f, "Property \"{name}\" not found.") } } } } zbus-lockstep-0.5.1/src/lib.rs000064400000000000000000000315361046102023000143470ustar 00000000000000//! # zbus-lockstep //! //! Is a collection of helpers for retrieving `DBus` type signatures from XML descriptions. //! Useful for comparing these with your types' signatures to ensure that they are compatible. //! //! It offers functions that retrieve the signature of a method's argument type, of a method's //! return type, pf a signal's body type or of a property's type from `DBus` XML. //! //! These functions require that you provide the file path to the XML file, the interface name, //! and the interface member wherein the signature resides. //! //! Corresponding to each of these functions, macros are provided which do not //! require you to exactly point out where the signature is found. These will just search //! by interface member name. //! //! The macros assume that the file path to the XML files is either: //! //! - `xml` or `XML`, the default path for `DBus` XML files - or is set by the //! - `LOCKSTEP_XML_PATH`, the env variable that overrides the default. #![doc(html_root_url = "https://docs.rs/zbus-lockstep/0.5.1")] #![allow(clippy::missing_errors_doc)] mod error; mod macros; use std::{io::Read, str::FromStr}; pub use error::LockstepError; pub use macros::resolve_xml_path; pub use zbus_xml::{ self, ArgDirection::{In, Out}, Node, }; use zvariant::Signature; use LockstepError::{ArgumentNotFound, InterfaceNotFound, MemberNotFound, PropertyNotFound}; type Result = std::result::Result>; #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum MsgType { Method, Signal, Property, } /// Retrieve a signal's body type signature from `DBus` XML. /// /// If you provide an argument name, then the signature of that argument is returned. /// If you do not provide an argument name, then the signature of all arguments is returned. /// /// # Examples /// /// ```rust /// # use std::fs::File; /// # use std::io::{Seek, SeekFrom, Write}; /// # use tempfile::tempfile; /// use zvariant::{Signature, Type, OwnedObjectPath}; /// use zbus_lockstep::get_signal_body_type; /// /// let xml = r#" /// /// /// /// /// /// /// /// "#; /// /// let mut xml_file: File = tempfile().unwrap(); /// xml_file.write_all(xml.as_bytes()).unwrap(); /// xml_file.seek(SeekFrom::Start(0)).unwrap(); /// /// #[derive(Debug, PartialEq, Type)] /// #[zvariant(signature = "o")] /// struct DeviceEvent { /// device: OwnedObjectPath, /// } /// /// let interface_name = "org.freedesktop.bolt1.Manager"; /// let member_name = "DeviceAdded"; /// /// let signature = get_signal_body_type(xml_file, interface_name, member_name, None).unwrap(); /// /// assert_eq!(&signature, DeviceEvent::SIGNATURE); /// ``` pub fn get_signal_body_type( mut xml: impl Read, interface_name: &str, member_name: &str, arg: Option<&str>, ) -> Result { let node = Node::from_reader(&mut xml)?; let interfaces = node.interfaces(); let interface = interfaces .iter() .find(|iface| iface.name() == interface_name) .ok_or(InterfaceNotFound(interface_name.to_owned()))?; let signals = interface.signals(); let signal = signals .iter() .find(|signal| signal.name() == member_name) .ok_or(MemberNotFound(member_name.to_owned()))?; let signature = { if let Some(arg_name) = arg { let args = signal.args(); let arg = args .iter() .find(|arg| arg.name() == Some(arg_name)) .ok_or(ArgumentNotFound(arg_name.to_owned()))?; arg.ty().to_string() } else { signal .args() .iter() .map(|arg| arg.ty().to_string()) .collect::() } }; Ok(Signature::from_str(&signature).map_err(|_| "Invalid signature")?) } /// Retrieve the signature of a property's type from XML. /// /// # Examples /// /// ```rust /// use std::fs::File; /// use std::io::{Seek, SeekFrom, Write}; /// use tempfile::tempfile; /// use zvariant::Type; /// use zbus_lockstep::get_property_type; /// /// #[derive(Debug, PartialEq, Type)] /// struct InUse(bool); /// /// let xml = String::from(r#" /// /// /// /// /// /// "#); /// /// let mut xml_file: File = tempfile().unwrap(); /// xml_file.write_all(xml.as_bytes()).unwrap(); /// xml_file.seek(SeekFrom::Start(0)).unwrap(); /// /// let interface_name = "org.freedesktop.GeoClue2.Manager"; /// let property_name = "InUse"; /// /// let signature = get_property_type(xml_file, interface_name, property_name).unwrap(); /// assert_eq!(signature, *InUse::SIGNATURE); /// ``` pub fn get_property_type( mut xml: impl Read, interface_name: &str, property_name: &str, ) -> Result { let node = Node::from_reader(&mut xml)?; let interfaces = node.interfaces(); let interface = interfaces .iter() .find(|iface| iface.name() == interface_name) .ok_or(InterfaceNotFound(interface_name.to_string()))?; let properties = interface.properties(); let property = properties .iter() .find(|property| property.name() == property_name) .ok_or(PropertyNotFound(property_name.to_owned()))?; let signature = property.ty().to_string(); Ok(Signature::from_str(&signature).map_err(|_| "Invalid signature")?) } /// Retrieve the signature of a method's return type from XML. /// /// If you provide an argument name, then the signature of that argument is returned. /// If you do not provide an argument name, then the signature of all arguments is returned. /// /// /// # Examples /// /// ```rust /// use std::fs::File; /// use std::io::{Seek, SeekFrom, Write}; /// use tempfile::tempfile; /// use zvariant::Type; /// use zbus_lockstep::get_method_return_type; /// /// #[derive(Debug, PartialEq, Type)] /// #[repr(u32)] /// enum Role { /// Invalid, /// TitleBar, /// MenuBar, /// ScrollBar, /// } /// /// let xml = String::from(r#" /// /// /// /// /// /// /// /// "#); /// /// let mut xml_file: File = tempfile().unwrap(); /// xml_file.write_all(xml.as_bytes()).unwrap(); /// xml_file.seek(SeekFrom::Start(0)).unwrap(); /// /// let interface_name = "org.a11y.atspi.Accessible"; /// let member_name = "GetRole"; /// /// let signature = get_method_return_type(xml_file, interface_name, member_name, None).unwrap(); /// assert_eq!(signature, *Role::SIGNATURE); /// ``` pub fn get_method_return_type( mut xml: impl Read, interface_name: &str, member_name: &str, arg_name: Option<&str>, ) -> Result { let node = Node::from_reader(&mut xml)?; let interfaces = node.interfaces(); let interface = interfaces .iter() .find(|iface| iface.name() == interface_name) .ok_or(InterfaceNotFound(interface_name.to_string()))?; let methods = interface.methods(); let method = methods .iter() .find(|method| method.name() == member_name) .ok_or(MemberNotFound(member_name.to_string()))?; let args = method.args(); let signature = { if arg_name.is_some() { args.iter() .find(|arg| arg.name() == arg_name) .ok_or(ArgumentNotFound( arg_name.expect("arg_name guarded by 'is_some'").to_string(), ))? .ty() .to_string() } else { args.iter() .filter(|arg| arg.direction() == Some(Out)) .map(|arg| arg.ty().to_string()) .collect::() } }; Ok(Signature::from_str(&signature).map_err(|_| "Invalid signature")?) } /// Retrieve the signature of a method's argument type from XML. /// /// Useful when one or more arguments, used to call a method, outline a useful type. /// /// If you provide an argument name, then the signature of that argument is returned. /// If you do not provide an argument name, then the signature of all arguments to the call is /// returned. /// /// # Examples /// /// ```rust /// use std::fs::File; /// use std::collections::HashMap; /// use std::io::{Seek, SeekFrom, Write}; /// use tempfile::tempfile; /// use zvariant::{Type, Value}; /// use zbus_lockstep::get_method_args_type; /// /// let xml = r#" /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// "#; /// /// #[derive(Debug, PartialEq, Type)] /// struct Notification<'a> { /// app_name: String, /// replaces_id: u32, /// app_icon: String, /// summary: String, /// body: String, /// actions: Vec, /// hints: HashMap>, /// expire_timeout: i32, /// } /// /// let mut xml_file = tempfile().unwrap(); /// xml_file.write_all(xml.as_bytes()).unwrap(); /// xml_file.seek(SeekFrom::Start(0)).unwrap(); /// /// let interface_name = "org.freedesktop.Notifications"; /// let member_name = "Notify"; /// /// let signature = get_method_args_type(xml_file, interface_name, member_name, None).unwrap(); /// assert_eq!(&signature, Notification::SIGNATURE); /// ``` pub fn get_method_args_type( mut xml: impl Read, interface_name: &str, member_name: &str, arg_name: Option<&str>, ) -> Result { let node = Node::from_reader(&mut xml)?; let interfaces = node.interfaces(); let interface = interfaces .iter() .find(|iface| iface.name() == interface_name) .ok_or(InterfaceNotFound(interface_name.to_owned()))?; let methods = interface.methods(); let method = methods .iter() .find(|method| method.name() == member_name) .ok_or(member_name.to_owned())?; let args = method.args(); let signature = if arg_name.is_some() { args.iter() .find(|arg| arg.name() == arg_name) .ok_or(ArgumentNotFound( arg_name.expect("arg_name guarded by is_some").to_string(), ))? .ty() .to_string() } else { args.iter() .filter(|arg| arg.direction() == Some(In)) .map(|arg| arg.ty().to_string()) .collect::() }; Ok(Signature::from_str(&signature).map_err(|_| "Invalid signature")?) } #[cfg(test)] mod test { use std::io::{Seek, SeekFrom, Write}; use tempfile::tempfile; use zvariant::{OwnedObjectPath, Type}; use crate::get_signal_body_type; #[test] fn test_get_signature_of_cache_add_accessible() { #[derive(Debug, PartialEq, Type)] struct Accessible { name: String, path: OwnedObjectPath, } #[derive(Debug, PartialEq, Type)] struct CacheItem { obj: Accessible, application: Accessible, parent: Accessible, index_in_parent: i32, child_count: i32, interfaces: Vec, name: String, role: u32, description: String, state_set: Vec, } let xml = r#" "#; let mut xml_file = tempfile().unwrap(); xml_file.write_all(xml.as_bytes()).unwrap(); xml_file.seek(SeekFrom::Start(0)).unwrap(); let interface_name = "org.a11y.atspi.Cache"; let member_name = "AddAccessible"; let signature = get_signal_body_type(xml_file, interface_name, member_name, None).unwrap(); assert_eq!(signature, *CacheItem::SIGNATURE); } } zbus-lockstep-0.5.1/src/macros.rs000064400000000000000000000764531046102023000150740ustar 00000000000000#![allow(unused_macros)] #![allow(dead_code)] #![allow(unused_imports)] use std::{fs, path::PathBuf, str::FromStr}; use crate::Result; /// Resolve XML path from either: /// /// - provided argument, /// - default location (`xml/`, `XML/`, `../xml` or `../XML`) or /// - env_variable (`LOCKSTEP_XML_PATH`) /// /// If no XML path is provided, it tries to find the default XML path. /// If the environment variable is set, it overrides the default, or /// argument path. /// /// # Example /// /// ```rust /// # use zbus_lockstep::resolve_xml_path; /// # use std::path::PathBuf; /// # fn main() { /// // path to XML files /// std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// /// let xml_path = resolve_xml_path(None).unwrap(); /// assert_eq!(xml_path, PathBuf::from("../xml").canonicalize().unwrap()); /// # } /// ``` /// # Panics /// /// Panics if no XML path is provided and the default XML path is not found. pub fn resolve_xml_path(xml: Option<&str>) -> Result { let mut xml = xml; let current_dir: PathBuf = PathBuf::from( std::env::var("CARGO_MANIFEST_DIR") .expect("the CARGO_MANIFEST_DIR environment variable should be set"), ); // We want to know the name of the crate we are expanded in. let crate_name = std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| String::from("unknown")); let current_dir_lower_case = current_dir.join("xml"); let current_dir_upper_case = current_dir.join("XML"); let parent_dir_lower_case = current_dir.join("../xml"); let parent_dir_upper_case = current_dir.join("../XML"); let crate_dir_lower_case = current_dir.join(&crate_name).join("xml"); let crate_dir_upper_case = current_dir.join(&crate_name).join("XML"); // If no XML path is provided, try to find the default XML path. if xml.is_none() { if current_dir_lower_case.exists() { xml = Some( current_dir_lower_case .to_str() .expect("current_dir_lower_case is valid UTF-8"), ); } if current_dir_upper_case.exists() { xml = Some( current_dir_upper_case .to_str() .expect("current_dir_upper_case is valid UTF-8"), ); } if parent_dir_lower_case.exists() { xml = Some( parent_dir_lower_case .to_str() .expect("parent_dir_lower_case is valid UTF-8"), ); } if parent_dir_upper_case.exists() { xml = Some( parent_dir_upper_case .to_str() .expect("parent_dir_upper_case is valid UTF-8"), ); } if crate_dir_lower_case.exists() { xml = Some( crate_dir_lower_case .to_str() .expect("crate_dir_lower_case is valid UTF-8"), ); } if crate_dir_upper_case.exists() { xml = Some( crate_dir_upper_case .to_str() .expect("crate_dir_upper_case is valid UTF-8"), ); } } let env_xml_path = std::env::var("LOCKSTEP_XML_PATH"); if env_xml_path.is_ok() { // Override the default, or argument path if the environment variable is set. xml = env_xml_path.as_ref().map(|s| s.as_str()).ok(); } // If no XML path is provided and the default XML path is not found, panic. if xml.is_none() { panic!( "No XML path provided and default XML path not found. Current dir: \"{}\" ", current_dir.to_str().expect("current_dir is valid UTF-8") ); } // Convert, canonicalize and return the XML path. let xml = PathBuf::from_str(xml.unwrap())?; Ok(xml.canonicalize()?) } /// A generic helper to find the file path and interface name of a member. #[doc(hidden)] #[macro_export] macro_rules! find_definition_in_dbus_xml { ($xml_path_buf:expr, $member:expr, $iface:expr, $msg_type:expr) => {{ use $crate::MsgType; let xml_path_buf: std::path::PathBuf = $xml_path_buf; let member: &str = $member; let iface: Option = $iface; let msg_type: MsgType = $msg_type; let mut xml_file_path = None; let mut interface_name = None; let read_dir = std::fs::read_dir(&xml_path_buf).expect("Failed to read XML directory"); // Walk the XML files in the directory. for entry in read_dir { let entry = entry.expect("Failed to read entry"); // Skip directories and non-XML files. if entry.path().is_dir() || entry.path().extension().unwrap() != "xml" { continue; } let entry_path = entry.path().clone(); let file = std::fs::File::open(entry.path()).expect("Failed to open file"); let node = $crate::zbus_xml::Node::from_reader(file).expect("Failed to parse XML file"); for interface in node.interfaces() { // If called with an `iface` arg, skip he interfaces that do not match. if iface.is_some() && interface.name().as_str() != iface.clone().unwrap() { continue; } match msg_type { MsgType::Method => { for dbus_item in interface.methods() { if dbus_item.name() == member { if interface_name.is_some() { panic!( "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.", msg_type, member ); } interface_name = Some(interface.name().to_string()); xml_file_path = Some(entry_path.clone()); continue; } } } MsgType::Signal => { for dbus_item in interface.signals() { if dbus_item.name() == member { if interface_name.is_some() { panic!( "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.", msg_type, member ); } interface_name = Some(interface.name().to_string()); xml_file_path = Some(entry_path.clone()); continue; } } } MsgType::Property => { for dbus_item in interface.properties() { if dbus_item.name() == member { if interface_name.is_some() { panic!( "Multiple interfaces offer the same {:?} member: {}, please specify the interface name.", msg_type, member ); } interface_name = Some(interface.name().to_string()); xml_file_path = Some(entry_path.clone()); continue; } } } }; } } // If the interface member was not found, return an error. if xml_file_path.is_none() { panic!("Member not found in XML files."); } (xml_file_path.unwrap(), interface_name.unwrap()) }}; } /// Retrieve the signature of a method's return type. /// /// This macro will take a method member name and return the signature of the /// return type. /// /// Essentially a wrapper around [`zbus_lockstep::get_method_return_type`], /// but this macro tries to do its job with less arguments. /// /// It will search in the XML specification of the method for the return type /// and return the signature of that type. /// /// If multiple interfaces offer the same method, you will need to specify the /// interface name as well. /// /// This macro can be called with or without the interface name. /// /// # Examples /// /// Basic usage: /// /// ```rust /// use std::str::FromStr; /// use zbus_lockstep::method_return_signature; /// use zvariant::Signature; /// /// std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// /// let sig = method_return_signature!("RequestName"); /// assert_eq!(&sig, &Signature::from_str("u").expect("Valid signature pattern")); /// ``` /// The macro supports colling arguments with identifiers as well as without. /// The macro may also be called with an interface name or interface and argument name: /// /// ```rust /// # use zbus_lockstep::{method_return_signature}; /// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// let _sig = method_return_signature!("RequestName", "org.example.Node", "grape"); /// /// // or alternatively /// /// let _sig = method_return_signature!(member: "RequestName", interface: "org.example.Node", argument: "grape"); /// ``` #[macro_export] macro_rules! method_return_signature { ($member:expr) => {{ use $crate::MsgType; let member = $member; // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_return_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr) => { $crate::method_return_signature!($member) }; ($member:expr, $interface:expr) => {{ let member = $member; use $crate::MsgType; let interface = Some($interface.to_string()); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_return_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr, interface: $interface:expr) => { $crate::method_return_signature!($member, $interface) }; ($member:expr, $interface:expr, $argument:expr) => {{ let member = $member; use $crate::MsgType; let interface = Some($interface.to_string()); let argument = Some($argument); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_return_type(file, &interface_name, member, argument) .expect("Failed to get method argument(s) type signature") }}; (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => { $crate::method_return_signature!($member, $interface, $argument) }; } /// Retrieve the signature of a method's arguments. /// /// Essentially a wrapper around [`zbus_lockstep::get_method_args_type`], /// but this macro tries to do its job with less arguments. /// /// This macro will take a method member name and return the signature of the /// arguments type. /// /// It will search in the XML specification of the method for the arguments type /// and return the signature of that type. /// /// If multiple interfaces offer the same member, you will need to /// specify the interface name as well. /// /// This macro can be called with or without the interface name. /// /// # Examples /// /// ```rust /// use std::str::FromStr; /// use zbus_lockstep::method_args_signature; /// use zvariant::Signature; /// /// std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// /// let sig = method_args_signature!("RequestName"); /// assert_eq!(&sig, &Signature::from_str("(su)").expect("Valid signature pattern")); /// ``` /// The macro supports colling arguments with identifiers as well as without. /// The macro may also be called with an interface name or interface and argument name: /// /// ```rust /// # use zbus_lockstep::{method_args_signature}; /// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// let _sig = method_args_signature!("RequestName", "org.example.Node", "apple"); /// /// // or alternatively /// /// let _sig = method_args_signature!(member: "RequestName", interface: "org.example.Node", argument: "apple"); /// ``` #[macro_export] macro_rules! method_args_signature { ($member:expr) => {{ use $crate::MsgType; let member = $member; // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_args_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr) => { $crate::method_args_signature!($member) }; ($member:expr, $interface:expr) => {{ use $crate::MsgType; let member = $member; let interface = Some($interface.to_string()); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_args_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr, interface: $interface:expr) => { $crate::method_args_signature!($member, $interface) }; ($member:expr, $interface:expr, $argument:expr) => {{ use $crate::MsgType; let member = $member; let interface = Some($interface.to_string()); let argument = Some($argument); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Method); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_method_args_type(file, &interface_name, member, argument) .expect("Failed to get method argument(s) type signature") }}; (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => { $crate::method_args_signature!($member, $interface, $argument) }; } /// Retrieve the signature of a signal's body type. /// /// Essentially a wrapper around [`zbus_lockstep::get_signal_body_type`], /// but this macro tries to find it with less arguments. /// /// This macro will take a signal member name and return the signature of the /// signal body type. /// /// If multiple interfaces offer the same member, you will need to /// specify the interface name as well. /// /// This macro can be called with or without the interface name. /// /// # Examples /// /// ```rust /// use std::str::FromStr; /// use zbus_lockstep::signal_body_type_signature; /// use zvariant::Signature; /// /// std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// /// let sig = signal_body_type_signature!("AddNode"); /// assert_eq!(&sig, &Signature::from_str("(so)").expect("Valid signature pattern")); /// ``` /// The macro supports colling arguments with identifiers as well as without. /// The macro may also be called with an interface name or interface and argument name: /// /// ```rust /// # use zbus_lockstep::{signal_body_type_signature}; /// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// let _sig = signal_body_type_signature!("Alert", "org.example.Node", "color"); /// /// // or alternatively /// /// let _sig = signal_body_type_signature!(member: "Alert", interface: "org.example.Node", argument: "color"); /// ``` #[macro_export] macro_rules! signal_body_type_signature { ($member:expr) => {{ use $crate::MsgType; let member = $member; // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Signal); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_signal_body_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr) => { $crate::signal_body_type_signature!($member) }; ($member:expr, $interface:expr) => {{ use $crate::MsgType; let member = $member; let interface = Some($interface.to_string()); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_signal_body_type(file, &interface_name, member, None) .expect("Failed to get method arguments type signature") }}; (member: $member:expr, interface: $interface:expr) => { $crate::signal_body_type_signature!($member, $interface) }; ($member:expr, $interface:expr, $argument:expr) => {{ use $crate::MsgType; let member = $member; let interface = Some($interface.to_string()); let argument = Some($argument); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Signal); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_signal_body_type(file, &interface_name, member, argument) .expect("Failed to get method argument(s) type signature") }}; (member: $member:expr, interface: $interface:expr, argument: $argument:expr) => { $crate::signal_body_type_signature!($member, $interface, $argument) }; } /// Retrieve the signature of a property's type. /// /// Essentially a wrapper around [`zbus_lockstep::get_property_type`], /// but this macro tries to do with less arguments. /// /// This macro will take a property name and return the signature of the /// property's type. /// /// If multiple interfaces offer the same member, you will need to /// specify the interface name as well. /// /// This macro can be called with or without the interface name. /// /// # Examples /// /// ```rust /// use std::str::FromStr; /// use zbus_lockstep::property_type_signature; /// use zvariant::Signature; /// /// std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// /// let sig = property_type_signature!("Features"); /// assert_eq!(&sig, &Signature::from_str("as").expect("Valid signature pattern")); /// ``` /// The member name and/or interface name can be used tp identify the arguments: /// /// ```rust /// # use zbus_lockstep::{property_type_signature}; /// # std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); /// let _sig = property_type_signature!(member: "Features", interface: "org.example.Node"); /// ``` #[macro_export] macro_rules! property_type_signature { ($member:expr) => {{ use $crate::MsgType; let member = $member; // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, None, MsgType::Property); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_property_type(file, &interface_name, member) .expect("Failed to get property type signature") }}; (member: $member:expr) => { $crate::property_type_signature!($member) }; ($member:expr, $interface:expr) => {{ use $crate::MsgType; let member = $member; let interface = Some($interface.to_string()); // Looking for default path or path specified by environment variable. let current_dir: std::path::PathBuf = std::env::current_dir().unwrap(); let xml_path = $crate::resolve_xml_path(None).expect(&format!( "Failed to resolve XML path, current dir: {}", current_dir.to_str().unwrap() )); // Find the definition of the method in the XML specification. let (file_path, interface_name) = $crate::find_definition_in_dbus_xml!(xml_path, member, interface, MsgType::Property); let file = std::fs::File::open(file_path).expect("Failed to open file"); $crate::get_property_type(file, &interface_name, member) .expect("Failed to get property type signature") }}; (member: $member:expr, interface: $interface:expr) => { $crate::property_type_signature!($member, $interface) }; } #[cfg(test)] mod test { use std::str::FromStr; use zvariant::Signature; use crate::signal_body_type_signature; #[test] fn test_signal_body_signature_macro() { // path to XML files can be set by environment variable // std::env::set_var("LOCKSTEP_XML_PATH", "../xml"); // But `resolve_xml_path` can find the `xml` in parent by itself. let sig = crate::signal_body_type_signature!("AddNode"); assert_eq!( &sig, &zvariant::Signature::from_str("(so)").expect("Valid signature pattern") ); } #[test] fn test_signal_body_signature_macro_with_identifier() { let sig = crate::signal_body_type_signature!(member: "AddNode"); assert_eq!( sig, Signature::from_str("(so)").expect("Valid signature pattern") ); } #[test] fn test_signal_body_signature_macro_with_interface() { let sig = crate::signal_body_type_signature!("AddNode", "org.example.Node"); assert_eq!( sig, Signature::from_str("(so)").expect("Valid signature pattern") ); } #[test] fn test_signal_body_signature_macro_with_interface_and_identifiers() { let sig = crate::signal_body_type_signature!(member: "AddNode", interface: "org.example.Node"); assert_eq!( sig, Signature::from_str("(so)").expect("Valid signature pattern") ); } #[test] fn test_signal_body_signature_macro_with_argument_and_interface() { let sig = crate::signal_body_type_signature!("Alert", "org.example.Node", "volume"); assert_eq!( sig, Signature::from_str("d").expect("Valid signature pattern") ); } #[test] fn test_signal_body_signature_macro_with_argument_and_identifiers_and_interface() { let sig = crate::signal_body_type_signature!( member: "Alert", interface: "org.example.Node", argument: "urgent" ); assert_eq!( sig, Signature::from_str("b").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro() { let sig = crate::method_args_signature!("RequestName"); assert_eq!( sig, Signature::from_str("(su)").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro_with_identifier() { let sig = crate::method_args_signature!(member: "RequestName"); assert_eq!( sig, Signature::from_str("(su)").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro_with_interface() { let sig = crate::method_args_signature!("RequestName", "org.example.Node"); assert_eq!( sig, Signature::from_str("(su)").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro_with_interface_and_identifiers() { let sig = crate::method_args_signature!(member: "RequestName", interface: "org.example.Node"); assert_eq!( sig, Signature::from_str("(su)").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro_with_argument_and_interface() { let sig = crate::method_args_signature!("RequestName", "org.example.Node", "apple"); assert_eq!( sig, Signature::from_str("s").expect("Valid signature pattern") ); } #[test] fn test_method_args_signature_macro_with_argument_and_identifiers_and_interface() { let sig = crate::method_args_signature!( member: "RequestName", interface: "org.example.Node", argument: "orange" ); assert_eq!( sig, Signature::from_str("u").expect("Valid signature pattern") ); } #[test] fn test_method_return_signature_macro() { let sig = crate::method_return_signature!("RequestName"); assert_eq!( sig, Signature::from_str("u").expect("Valid signatuee pattern") ); } #[test] fn test_method_return_signature_macro_with_identifier() { let sig = crate::method_return_signature!(member: "RequestName"); assert_eq!( sig, Signature::from_str("u").expect("Valid signature pattern") ); } #[test] fn test_method_return_signature_macro_with_interface() { let sig = crate::method_return_signature!("RequestName", "org.example.Node"); assert_eq!( sig, Signature::from_str("u").expect("Valid signature pattern") ); } #[test] fn test_method_return_signature_macro_with_interface_and_identifiers() { let sig = crate::method_return_signature!(member: "RequestName", interface: "org.example.Node"); assert_eq!( sig, Signature::from_str("u").expect("Vlaid signature pattern") ); } #[test] fn test_method_return_signature_macro_with_argument_and_interface() { let sig = crate::method_return_signature!("RequestName", "org.example.Node", "grape"); assert_eq!( sig, Signature::from_str("u").expect("Vlaid signature pattern") ); } #[test] fn test_method_return_signature_macro_with_argument_and_identifiers_and_interface() { let sig = crate::method_return_signature!( member: "RequestName", interface: "org.example.Node", argument: "grape" ); assert_eq!( sig, Signature::from_str("u").expect("Vlaid signature pattern") ); } #[test] fn test_property_type_signature_macro() { let sig = crate::property_type_signature!("Features"); assert_eq!( sig, Signature::from_str("as").expect("Vlaid signature pattern") ); } #[test] fn test_property_type_signature_macro_with_identifier() { let sig = crate::property_type_signature!(member: "Features"); assert_eq!( sig, Signature::from_str("as").expect("Vlaid signature pattern") ); } #[test] fn test_property_type_signature_macro_with_interface() { let sig = crate::property_type_signature!("Features", "org.example.Node"); assert_eq!( sig, Signature::from_str("as").expect("Vlaid signature pattern") ); } #[test] fn test_property_type_signature_macro_with_interface_and_identifiers() { let sig = crate::property_type_signature!(member: "Features", interface: "org.example.Node"); assert_eq!( sig, Signature::from_str("as").expect("Vlaid signature pattern") ); } }