zbus_names-4.3.1/.cargo_vcs_info.json0000644000000001500000000000100132030ustar { "git": { "sha1": "d3b3a2a2fb60831ca59772e8b94d28ce79e59169" }, "path_in_vcs": "zbus_names" }zbus_names-4.3.1/CHANGELOG.md000064400000000000000000000017701046102023000136150ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 4.3.1 - 2026-01-09 ### Fixed - 🐛 add inherent `as_ref()` to owned types. ### Other - 🤖 release-plz: Fix formatting of CHANGELOG files. - 🤖 release-plz: Use the default header in changelog. ## 4.3.0 - 2026-01-09 ### Added - ✨ Implement Borrow for Owned* types. ### Changed - ♻️ Reduce code duplication with `define_name_type_impls!` macro. - 🎨 Format all files (rust 1.85). - 🚚 Update name of Github space from dbus2 to z-galaxy. ### Documentation - 📝 doc typo, Error names have same constraints as *interface* names. ### Fixed - 🩹 Don't use workspace for local deps. ### Other - 👽️ Use `std::hint::black_box` in benchmarks code. - 🧑‍💻 Use workspace dependencies. ### Removed - ➖ Drop `static_assertions` dep. zbus_names-4.3.1/Cargo.lock0000644000000564600000000000100111750ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "aho-corasick" version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "anes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anyhow" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "approx" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ "num-traits", ] [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bumpalo" version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "ciborium" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", "serde", ] [[package]] name = "ciborium-io" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", ] [[package]] name = "clap" version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstyle", "clap_lex", ] [[package]] name = "clap_lex" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "codspeed" version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f0d98d97fd75ca4489a1a0997820a6521531085e7c8a98941bd0e1264d567dd" dependencies = [ "anyhow", "cc", "colored", "getrandom", "glob", "libc", "nix", "serde", "serde_json", "statrs", ] [[package]] name = "codspeed-criterion-compat" version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d16fe2db207123f7b3a3b5cfff0c22f99469f7534145f3573f57f4c8a5653c2c" dependencies = [ "clap", "codspeed", "codspeed-criterion-compat-walltime", "colored", "regex", ] [[package]] name = "codspeed-criterion-compat-walltime" version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035c7f9846b143aeabb3833f5b584023eb97b43ecbff3d997db74c4372df2bd" dependencies = [ "anes", "cast", "ciborium", "clap", "codspeed", "criterion-plot", "is-terminal", "itertools", "num-traits", "once_cell", "oorandom", "plotters", "rayon", "regex", "serde", "serde_derive", "serde_json", "tinytemplate", "walkdir", ] [[package]] name = "colored" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", "windows-sys 0.59.0", ] [[package]] name = "criterion-plot" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", ] [[package]] name = "crossbeam-deque" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "endi" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" [[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 = "find-msvc-tools" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "getrandom" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", "wasi", ] [[package]] name = "glob" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "half" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", "zerocopy", ] [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hermit-abi" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "indexmap" version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "is-terminal" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", "windows-sys 0.61.2", ] [[package]] name = "itertools" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "nix" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags", "cfg-if", "cfg_aliases", "libc", ] [[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "plotters" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", "plotters-svg", "wasm-bindgen", "web-sys", ] [[package]] name = "plotters-backend" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] [[package]] name = "proc-macro-crate" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", ] [[package]] name = "rayon-core" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", ] [[package]] name = "regex" version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", "serde", "serde_core", "zmij", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "statrs" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" dependencies = [ "approx", "num-traits", ] [[package]] name = "syn" version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tinytemplate" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ "serde", "serde_json", ] [[package]] name = "toml_datetime" version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", "toml_parser", "winnow", ] [[package]] name = "toml_parser" version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] name = "unicode-ident" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "walkdir" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", ] [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] name = "zbus_names" version = "4.3.1" dependencies = [ "codspeed-criterion-compat", "serde", "winnow", "zvariant", ] [[package]] name = "zerocopy" version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "zmij" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d6085d62852e35540689d1f97ad663e3971fc19cf5eceab364d62c646ea167" [[package]] name = "zvariant" version = "5.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "788ca131e3757991e4b9fe9f7b78ae302749ed96093ff60858a1f4732b04b164" dependencies = [ "endi", "enumflags2", "serde", "winnow", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" version = "5.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e69a2f6b221a6fec9bd6bcc77c19360cca106f92a5fd948b8aa17d2339c7505" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", "zvariant_utils", ] [[package]] name = "zvariant_utils" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" dependencies = [ "proc-macro2", "quote", "serde", "syn", "winnow", ] zbus_names-4.3.1/Cargo.toml0000644000000027700000000000100112130ustar # 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 = "2024" rust-version = "1.85" name = "zbus_names" version = "4.3.1" authors = ["Zeeshan Ali Khan "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "A collection of D-Bus bus names types" readme = "README.md" keywords = [ "D-Bus", "DBus", "IPC", ] categories = ["os::unix-apis"] license = "MIT" repository = "https://github.com/z-galaxy/zbus/" resolver = "2" [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] [lib] name = "zbus_names" path = "src/lib.rs" bench = false [[bench]] name = "benchmarks" path = "benches/benchmarks.rs" harness = false [dependencies.serde] version = "1.0.200" features = ["derive"] [dependencies.winnow] version = "0.7" [dependencies.zvariant] version = "5.9.0" features = ["enumflags2"] [dev-dependencies.criterion] version = "4.0.4" package = "codspeed-criterion-compat" [lints.rust.unexpected_cfgs] level = "warn" priority = 0 check-cfg = ["cfg(tokio_unstable)"] zbus_names-4.3.1/Cargo.toml.orig000064400000000000000000000013651046102023000146730ustar 00000000000000[package] name = "zbus_names" version = "4.3.1" authors = ["Zeeshan Ali Khan "] edition = { workspace = true } rust-version = { workspace = true } description = "A collection of D-Bus bus names types" repository = { workspace = true } keywords = ["D-Bus", "DBus", "IPC"] license = { workspace = true } categories = ["os::unix-apis"] readme = "README.md" [dependencies] zvariant = { path = "../zvariant", features = [ "enumflags2", ], version = "5.9.0" } serde.workspace = true winnow.workspace = true [dev-dependencies] criterion.workspace = true [lib] bench = false [[bench]] name = "benchmarks" harness = false [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] [lints] workspace = true zbus_names-4.3.1/LICENSE000064400000000000000000000020701046102023000130030ustar 00000000000000Copyright (c) 2024 Zeeshan Ali Khan & zbus contributors Permission 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_names-4.3.1/README.md000064400000000000000000000013721046102023000132610ustar 00000000000000# zbus_names [![](https://docs.rs/zbus_names/badge.svg)](https://docs.rs/zbus_names/) [![](https://img.shields.io/crates/v/zbus_names)](https://crates.io/crates/zbus_names) This crate provides collection of types for various [D-Bus bus names][dbn]. This is used by [`zbus`] (and in future by [`zbus_macros`] as well) crate. Other D-Bus crates are also encouraged to use this API in the spirit of cooperation. :) For convenience, `zbus` re-exports this crate as `names`, so you do not need to depend directly on this crate if you already depend on `zbus`. **Status:** Stable. [dbn]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names [`zbus`]: https://crates.io/crates/zbus [`zbus_macros`]: https://crates.io/crates/zbus_macros zbus_names-4.3.1/benches/benchmarks.rs000064400000000000000000000037631046102023000161020ustar 00000000000000use criterion::{Criterion, criterion_group, criterion_main}; use std::hint::black_box; fn name_parse(c: &mut Criterion) { const WELL_KNOWN_NAME: &str = "a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name.\ That.Is.Valid.For.DBus.and_good.For.benchmarks.I-guess"; const UNIQUE_NAME: &str = ":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name.\ That.Is.Valid.For.DBus.and_good.For.benchmarks.I-guess"; const INTERFACE_NAME: &str = "a.very.loooooooooooooooooo_ooooooo_0000o0ng.Name.\ That.Is.Valid.For.DBus.and_good.For.benchmarks.I_guess"; const MEMBER_NAME: &str = "a_very_loooooooooooooooooo_ooooooo_0000o0ng_Name_\ That_Is_Valid_For_DBus_and_good_For_benchmarks_I_guess"; let mut group = c.benchmark_group("parse_name"); group.sample_size(1000); group.bench_function("well_known", |b| { b.iter(|| { zbus_names::WellKnownName::try_from(black_box(WELL_KNOWN_NAME)).unwrap(); }) }); group.bench_function("unique", |b| { b.iter(|| { zbus_names::UniqueName::try_from(black_box(UNIQUE_NAME)).unwrap(); }) }); group.bench_function("bus", |b| { b.iter(|| { // Use a well-known name since the parser first tries unique name. zbus_names::BusName::try_from(black_box(WELL_KNOWN_NAME)).unwrap(); }) }); group.bench_function("interface", |b| { b.iter(|| { zbus_names::InterfaceName::try_from(black_box(INTERFACE_NAME)).unwrap(); }) }); group.bench_function("error", |b| { b.iter(|| { // Error names follow the same rules are interface names. zbus_names::ErrorName::try_from(black_box(INTERFACE_NAME)).unwrap(); }) }); group.bench_function("member", |b| { b.iter(|| { zbus_names::MemberName::try_from(black_box(MEMBER_NAME)).unwrap(); }) }); group.finish(); } criterion_group!(benches, name_parse); criterion_main!(benches); zbus_names-4.3.1/src/bus_name.rs000064400000000000000000000346351046102023000147400ustar 00000000000000use core::{ borrow::Borrow, fmt::{self, Debug, Display, Formatter}, ops::Deref, }; use std::{borrow::Cow, sync::Arc}; use crate::{ Error, OwnedUniqueName, OwnedWellKnownName, Result, UniqueName, WellKnownName, unique_name, utils::impl_str_basic, well_known_name, }; use serde::{Deserialize, Serialize, de}; use zvariant::{NoneValue, OwnedValue, Str, Type, Value}; /// String that identifies a [bus name]. /// /// # Examples /// /// ``` /// use zbus_names::BusName; /// /// // Valid well-known names. /// let name = BusName::try_from("org.gnome.Service-for_you").unwrap(); /// assert!(matches!(name, BusName::WellKnown(_))); /// assert_eq!(name, "org.gnome.Service-for_you"); /// let name = BusName::try_from("a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap(); /// assert!(matches!(name, BusName::WellKnown(_))); /// assert_eq!(name, "a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name"); /// /// // Valid unique names. /// let name = BusName::try_from(":org.gnome.Service-for_you").unwrap(); /// assert!(matches!(name, BusName::Unique(_))); /// assert_eq!(name, ":org.gnome.Service-for_you"); /// let name = BusName::try_from(":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap(); /// assert!(matches!(name, BusName::Unique(_))); /// assert_eq!(name, ":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name"); /// /// // Invalid bus names /// BusName::try_from("").unwrap_err(); /// BusName::try_from("double..dots").unwrap_err(); /// BusName::try_from(".").unwrap_err(); /// BusName::try_from(".start.with.dot").unwrap_err(); /// BusName::try_from("1start.with.digit").unwrap_err(); /// BusName::try_from("no-dots").unwrap_err(); /// ``` /// /// [bus name]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize)] #[serde(untagged)] pub enum BusName<'name> { #[serde(borrow)] Unique(UniqueName<'name>), #[serde(borrow)] WellKnown(WellKnownName<'name>), } impl_str_basic!(BusName<'_>); impl BusName<'_> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> BusName<'_> { match self { BusName::Unique(name) => BusName::Unique(name.as_ref()), BusName::WellKnown(name) => BusName::WellKnown(name.as_ref()), } } /// The well-known-name as string. pub fn as_str(&self) -> &str { match self { BusName::Unique(name) => name.as_str(), BusName::WellKnown(name) => name.as_str(), } } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> BusName<'static> { match self { BusName::Unique(name) => BusName::Unique(name.to_owned()), BusName::WellKnown(name) => BusName::WellKnown(name.to_owned()), } } /// Creates an owned clone of `self`. pub fn into_owned(self) -> BusName<'static> { match self { BusName::Unique(name) => BusName::Unique(name.into_owned()), BusName::WellKnown(name) => BusName::WellKnown(name.into_owned()), } } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { match Self::try_from(name)? { BusName::Unique(_) => Ok(BusName::Unique(UniqueName::from_static_str_unchecked(name))), BusName::WellKnown(_) => Ok(BusName::WellKnown( WellKnownName::from_static_str_unchecked(name), )), } } } impl Deref for BusName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for BusName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Debug for BusName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { BusName::Unique(name) => f .debug_tuple("BusName::Unique") .field(&name.as_str()) .finish(), BusName::WellKnown(name) => f .debug_tuple("BusName::WellKnown") .field(&name.as_str()) .finish(), } } } impl Display for BusName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for BusName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for BusName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for BusName<'_> { fn eq(&self, other: &OwnedBusName) -> bool { *self == other.0 } } impl PartialEq> for BusName<'_> { fn eq(&self, other: &UniqueName<'_>) -> bool { match self { Self::Unique(name) => *name == *other, Self::WellKnown(_) => false, } } } impl PartialEq> for BusName<'_> { fn eq(&self, other: &WellKnownName<'_>) -> bool { match self { Self::Unique(_) => false, Self::WellKnown(name) => *name == *other, } } } impl<'name> NoneValue for BusName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } // Manual deserialize implementation to get the desired error on invalid bus names. impl<'de: 'name, 'name> Deserialize<'de> for BusName<'name> { fn deserialize(deserializer: D) -> core::result::Result where D: serde::Deserializer<'de>, { let name = >::deserialize(deserializer)?; Self::try_from(name).map_err(|e| de::Error::custom(e.to_string())) } } impl Type for BusName<'_> { const SIGNATURE: &'static zvariant::Signature = &zvariant::Signature::Str; } impl<'name> From> for BusName<'name> { fn from(name: UniqueName<'name>) -> Self { BusName::Unique(name) } } impl<'name> From> for BusName<'name> { fn from(name: WellKnownName<'name>) -> Self { BusName::WellKnown(name) } } impl<'s> TryFrom> for BusName<'s> { type Error = Error; fn try_from(value: Str<'s>) -> Result { if unique_name::validate_bytes(value.as_bytes()).is_ok() { Ok(BusName::Unique(UniqueName(value))) } else if well_known_name::validate_bytes(value.as_bytes()).is_ok() { Ok(BusName::WellKnown(WellKnownName(value))) } else { Err(Error::InvalidName(INVALID_BUS_NAME_ERROR)) } } } impl<'s> TryFrom> for WellKnownName<'s> { type Error = Error; fn try_from(value: BusName<'s>) -> Result { match value { BusName::Unique(_) => Err(Error::InvalidNameConversion { from: "UniqueName", to: "WellKnownName", }), BusName::WellKnown(name) => Ok(name), } } } impl<'s> TryFrom> for UniqueName<'s> { type Error = Error; fn try_from(value: BusName<'s>) -> Result { match value { BusName::Unique(name) => Ok(name), BusName::WellKnown(_) => Err(Error::InvalidNameConversion { from: "WellKnownName", to: "UniqueName", }), } } } impl<'s> TryFrom<&'s str> for BusName<'s> { type Error = Error; fn try_from(value: &'s str) -> Result { Str::from(value).try_into() } } impl TryFrom for BusName<'_> { type Error = Error; fn try_from(value: String) -> Result { Str::from(value).try_into() } } impl TryFrom> for BusName<'_> { type Error = Error; fn try_from(value: Arc) -> Result { Str::from(value).try_into() } } impl<'s> TryFrom> for BusName<'s> { type Error = Error; fn try_from(value: Value<'s>) -> Result { Str::try_from(value) .map_err(Into::into) .and_then(TryInto::try_into) } } /// This never succeeds but is provided so it's easier to pass `Option::None` values for API /// requiring `Option>`, since type inference won't work here. impl TryFrom<()> for BusName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work."); } } impl<'name> TryFrom> for BusName<'name> { type Error = Error; fn try_from(value: Cow<'name, str>) -> Result { Str::from(value).try_into() } } impl<'s> From> for Value<'s> { fn from(name: BusName<'s>) -> Self { match name { BusName::Unique(name) => name.into(), BusName::WellKnown(name) => name.into(), } } } impl<'name> From> for Str<'name> { fn from(value: BusName<'name>) -> Self { match value { BusName::Unique(name) => name.into(), BusName::WellKnown(name) => name.into(), } } } impl<'name> From<&BusName<'name>> for BusName<'name> { fn from(name: &BusName<'name>) -> Self { name.clone() } } impl TryFrom for BusName<'_> { type Error = Error; fn try_from(value: OwnedValue) -> Result { Str::try_from(value) .map_err(Into::into) .and_then(TryInto::try_into) } } impl TryFrom> for OwnedValue { type Error = Error; fn try_from(name: BusName<'static>) -> Result { match name { BusName::Unique(name) => name.try_into(), BusName::WellKnown(name) => name.try_into(), } .map_err(Into::into) } } impl From for BusName<'_> { fn from(name: OwnedUniqueName) -> Self { BusName::Unique(name.into()) } } impl<'a> From<&'a OwnedUniqueName> for BusName<'a> { fn from(name: &'a OwnedUniqueName) -> Self { BusName::Unique(name.into()) } } impl From for BusName<'_> { fn from(name: OwnedWellKnownName) -> Self { BusName::WellKnown(name.into()) } } impl<'a> From<&'a OwnedWellKnownName> for BusName<'a> { fn from(name: &'a OwnedWellKnownName) -> Self { BusName::WellKnown(name.into()) } } /// Owned sibling of [`BusName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, PartialOrd, Ord, Type)] pub struct OwnedBusName(#[serde(borrow)] BusName<'static>); impl_str_basic!(OwnedBusName); impl OwnedBusName { /// Convert to the inner `BusName`, consuming `self`. pub fn into_inner(self) -> BusName<'static> { self.0 } /// Get a reference to the inner `BusName`. pub fn inner(&self) -> &BusName<'static> { &self.0 } } impl Deref for OwnedBusName { type Target = BusName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl<'a> Borrow> for OwnedBusName { fn borrow(&self) -> &BusName<'a> { &self.0 } } impl Borrow for OwnedBusName { fn borrow(&self) -> &str { self.0.as_str() } } impl Debug for OwnedBusName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match &self.0 { BusName::Unique(name) => f .debug_tuple("OwnedBusName::Unique") .field(&name.as_str()) .finish(), BusName::WellKnown(name) => f .debug_tuple("OwnedBusName::WellKnown") .field(&name.as_str()) .finish(), } } } impl Display for OwnedBusName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&BusName::from(self), f) } } impl From for BusName<'_> { fn from(name: OwnedBusName) -> Self { name.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedBusName> for BusName<'unowned> { fn from(name: &'owned OwnedBusName) -> Self { match &name.0 { BusName::Unique(name) => BusName::Unique(UniqueName::from_str_unchecked(name)), BusName::WellKnown(name) => BusName::WellKnown(WellKnownName::from_str_unchecked(name)), } } } impl From> for OwnedBusName { fn from(name: BusName<'_>) -> Self { OwnedBusName(name.into_owned()) } } impl TryFrom<&'_ str> for OwnedBusName { type Error = Error; fn try_from(value: &str) -> Result { BusName::try_from(value).map(Self::from) } } impl TryFrom for OwnedBusName { type Error = Error; fn try_from(value: String) -> Result { BusName::try_from(value).map(Self::from) } } impl TryFrom> for OwnedBusName { type Error = Error; fn try_from(value: Cow<'_, str>) -> Result { BusName::try_from(value).map(Self::from) } } impl TryFrom> for OwnedBusName { type Error = Error; fn try_from(value: Value<'static>) -> Result { BusName::try_from(value).map(Self::from) } } impl From for Value<'_> { fn from(name: OwnedBusName) -> Self { name.0.into() } } impl TryFrom for OwnedBusName { type Error = Error; fn try_from(value: OwnedValue) -> Result { BusName::try_from(value).map(Self::from) } } impl TryFrom for OwnedValue { type Error = Error; fn try_from(name: OwnedBusName) -> Result { name.0.try_into() } } impl From for Str<'_> { fn from(value: OwnedBusName) -> Self { match value.0 { BusName::Unique(name) => name.into(), BusName::WellKnown(name) => name.into(), } } } impl<'de> Deserialize<'de> for OwnedBusName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| BusName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedBusName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedBusName { fn eq(&self, other: &BusName<'_>) -> bool { self.0 == *other } } impl NoneValue for OwnedBusName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { BusName::null_value() } } const INVALID_BUS_NAME_ERROR: &str = "Invalid bus name. \ See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus"; zbus_names-4.3.1/src/error.rs000064400000000000000000000124451046102023000142730ustar 00000000000000use std::{convert::Infallible, error, fmt}; use zvariant::Error as VariantError; /// The error type for `zbus_names`. /// /// The various errors that can be reported by this crate. #[derive(Clone, Debug)] #[non_exhaustive] pub enum Error { Variant(VariantError), /// Invalid bus name. The strings describe why the bus name is neither a valid unique nor /// well-known name, respectively. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidBusName(String, String), /// Invalid well-known bus name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidWellKnownName(String), /// Invalid unique bus name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidUniqueName(String), /// Invalid interface name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidInterfaceName(String), /// Invalid member (method or signal) name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidMemberName(String), /// Invalid property name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidPropertyName(String), /// Invalid error name. #[deprecated( since = "4.1.0", note = "This variant is no longer returned from any of our API.\ Use `Error::InvalidName` instead." )] InvalidErrorName(String), /// An invalid name. InvalidName(&'static str), /// Invalid conversion from name type `from` to name type `to`. InvalidNameConversion { from: &'static str, to: &'static str, }, } impl PartialEq for Error { #[allow(deprecated)] fn eq(&self, other: &Self) -> bool { match (self, other) { (Self::InvalidBusName(_, _), Self::InvalidBusName(_, _)) => true, (Self::InvalidWellKnownName(_), Self::InvalidWellKnownName(_)) => true, (Self::InvalidUniqueName(_), Self::InvalidUniqueName(_)) => true, (Self::InvalidInterfaceName(_), Self::InvalidInterfaceName(_)) => true, (Self::InvalidMemberName(_), Self::InvalidMemberName(_)) => true, (Self::InvalidPropertyName(_), Self::InvalidPropertyName(_)) => true, (Self::InvalidErrorName(_), Self::InvalidErrorName(_)) => true, (Self::InvalidName(_), Self::InvalidName(_)) => true, (Self::InvalidNameConversion { .. }, Self::InvalidNameConversion { .. }) => true, (Self::Variant(s), Self::Variant(o)) => s == o, (_, _) => false, } } } impl error::Error for Error { #[allow(deprecated)] fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { Error::InvalidBusName(_, _) => None, Error::InvalidWellKnownName(_) => None, Error::InvalidUniqueName(_) => None, Error::InvalidInterfaceName(_) => None, Error::InvalidErrorName(_) => None, Error::InvalidMemberName(_) => None, Error::InvalidPropertyName(_) => None, Error::InvalidName(_) => None, Error::InvalidNameConversion { .. } => None, Error::Variant(e) => Some(e), } } } impl fmt::Display for Error { #[allow(deprecated)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Variant(e) => write!(f, "{e}"), Error::InvalidBusName(unique_err, well_known_err) => { write!( f, "Neither a valid unique ({unique_err}) nor a well-known ({well_known_err}) bus name" ) } Error::InvalidWellKnownName(s) => write!(f, "Invalid well-known bus name: {s}"), Error::InvalidUniqueName(s) => write!(f, "Invalid unique bus name: {s}"), Error::InvalidInterfaceName(s) => write!(f, "Invalid interface or error name: {s}"), Error::InvalidErrorName(s) => write!(f, "Invalid interface or error name: {s}"), Error::InvalidMemberName(s) => write!(f, "Invalid method or signal name: {s}"), Error::InvalidPropertyName(s) => write!(f, "Invalid property name: {s}"), Error::InvalidName(s) => write!(f, "{s}"), Error::InvalidNameConversion { from, to } => { write!(f, "Invalid conversion from `{from}` to `{to}`") } } } } impl From for Error { fn from(val: VariantError) -> Self { Error::Variant(val) } } impl From for Error { fn from(i: Infallible) -> Self { match i {} } } /// Alias for a `Result` with the error type `zbus_names::Error`. pub type Result = std::result::Result; zbus_names-4.3.1/src/error_name.rs000064400000000000000000000040671046102023000152740ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies an [error name][en] on the bus. /// /// Error names have same constraints as interface names. /// /// # Examples /// /// ``` /// use zbus_names::ErrorName; /// /// // Valid error names. /// let name = ErrorName::try_from("org.gnome.Error_for_you").unwrap(); /// assert_eq!(name, "org.gnome.Error_for_you"); /// let name = ErrorName::try_from("a.very.loooooooooooooooooo_ooooooo_0000o0ng.ErrorName").unwrap(); /// assert_eq!(name, "a.very.loooooooooooooooooo_ooooooo_0000o0ng.ErrorName"); /// /// // Invalid error names /// ErrorName::try_from("").unwrap_err(); /// ErrorName::try_from(":start.with.a.colon").unwrap_err(); /// ErrorName::try_from("double..dots").unwrap_err(); /// ErrorName::try_from(".").unwrap_err(); /// ErrorName::try_from(".start.with.dot").unwrap_err(); /// ErrorName::try_from("no-dots").unwrap_err(); /// ErrorName::try_from("1st.element.starts.with.digit").unwrap_err(); /// ErrorName::try_from("the.2nd.element.starts.with.digit").unwrap_err(); /// ErrorName::try_from("contains.dashes-in.the.name").unwrap_err(); /// ``` /// /// [en]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct ErrorName<'name>(Str<'name>); /// Owned sibling of [`ErrorName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedErrorName(#[serde(borrow)] ErrorName<'static>); define_name_type_impls! { name: ErrorName, owned: OwnedErrorName, validate: validate, } fn validate(name: &str) -> Result<()> { // Error names follow the same rules as interface names. crate::interface_name::validate_bytes(name.as_bytes()).map_err(|_| { Error::InvalidName( "Invalid error name. See \ https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error", ) }) } zbus_names-4.3.1/src/interface_name.rs000064400000000000000000000062151046102023000161000ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies an [interface name][in] on the bus. /// /// # Examples /// /// ``` /// use zbus_names::InterfaceName; /// /// // Valid interface names. /// let name = InterfaceName::try_from("org.gnome.Interface_for_you").unwrap(); /// assert_eq!(name, "org.gnome.Interface_for_you"); /// let name = InterfaceName::try_from("a.very.loooooooooooooooooo_ooooooo_0000o0ng.Name").unwrap(); /// assert_eq!(name, "a.very.loooooooooooooooooo_ooooooo_0000o0ng.Name"); /// /// // Invalid interface names /// InterfaceName::try_from("").unwrap_err(); /// InterfaceName::try_from(":start.with.a.colon").unwrap_err(); /// InterfaceName::try_from("double..dots").unwrap_err(); /// InterfaceName::try_from(".").unwrap_err(); /// InterfaceName::try_from(".start.with.dot").unwrap_err(); /// InterfaceName::try_from("no-dots").unwrap_err(); /// InterfaceName::try_from("1st.element.starts.with.digit").unwrap_err(); /// InterfaceName::try_from("the.2nd.element.starts.with.digit").unwrap_err(); /// InterfaceName::try_from("contains.dashes-in.the.name").unwrap_err(); /// ``` /// /// [in]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct InterfaceName<'name>(Str<'name>); /// Owned sibling of [`InterfaceName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedInterfaceName(#[serde(borrow)] InterfaceName<'static>); define_name_type_impls! { name: InterfaceName, owned: OwnedInterfaceName, validate: validate, } fn validate(name: &str) -> Result<()> { validate_bytes(name.as_bytes()).map_err(|_| { Error::InvalidName( "Invalid interface name. See \ https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface" ) }) } pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> { use winnow::{ Parser, combinator::separated, stream::AsChar, token::{one_of, take_while}, }; // Rules // // * Only ASCII alphanumeric and `_` // * Must not begin with a `.`. // * Must contain at least one `.`. // * Each element must: // * not begin with a digit. // * be 1 character (so name must be minimum 3 characters long). // * <= 255 characters. // // Note: A `-` not allowed, which is why we can't use the same parser as for `WellKnownName`. let first_element_char = one_of((AsChar::is_alpha, b'_')); let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_')); let element = (first_element_char, subsequent_element_chars); let mut interface_name = separated(2.., element, b'.'); interface_name .parse(bytes) .map_err(|_| ()) .and_then(|_: ()| { // Least likely scenario so we check this last. if bytes.len() > 255 { return Err(()); } Ok(()) }) } zbus_names-4.3.1/src/lib.rs000064400000000000000000000013411046102023000137010ustar 00000000000000#![deny(rust_2018_idioms)] #![doc( html_logo_url = "https://raw.githubusercontent.com/z-galaxy/zbus/9f7a90d2b594ddc48b7a5f39fda5e00cd56a7dfb/logo.png" )] #![doc = include_str!("../README.md")] #![doc(test(attr( warn(unused), deny(warnings), allow(dead_code), // W/o this, we seem to get some bogus warning about `extern crate zbus`. allow(unused_extern_crates), )))] mod bus_name; pub use bus_name::*; mod unique_name; pub use unique_name::*; mod well_known_name; pub use well_known_name::*; mod interface_name; pub use interface_name::*; mod member_name; pub use member_name::*; mod property_name; pub use property_name::*; mod error; pub use error::*; mod error_name; pub use error_name::*; mod utils; zbus_names-4.3.1/src/member_name.rs000064400000000000000000000050711046102023000154060ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies an [member (method or signal) name][in] on the bus. /// /// # Examples /// /// ``` /// use zbus_names::MemberName; /// /// // Valid member names. /// let name = MemberName::try_from("Member_for_you").unwrap(); /// assert_eq!(name, "Member_for_you"); /// let name = MemberName::try_from("CamelCase101").unwrap(); /// assert_eq!(name, "CamelCase101"); /// let name = MemberName::try_from("a_very_loooooooooooooooooo_ooooooo_0000o0ngName").unwrap(); /// assert_eq!(name, "a_very_loooooooooooooooooo_ooooooo_0000o0ngName"); /// /// // Invalid member names /// MemberName::try_from("").unwrap_err(); /// MemberName::try_from(".").unwrap_err(); /// MemberName::try_from("1startWith_a_Digit").unwrap_err(); /// MemberName::try_from("contains.dots_in_the_name").unwrap_err(); /// MemberName::try_from("contains-dashes-in_the_name").unwrap_err(); /// ``` /// /// [in]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct MemberName<'name>(Str<'name>); /// Owned sibling of [`MemberName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedMemberName(#[serde(borrow)] MemberName<'static>); define_name_type_impls! { name: MemberName, owned: OwnedMemberName, validate: validate, } fn validate(name: &str) -> Result<()> { validate_bytes(name.as_bytes()).map_err(|_| { Error::InvalidName( "Invalid member name. See \ https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member", ) }) } pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> { use winnow::{ Parser, stream::AsChar, token::{one_of, take_while}, }; // Rules // // * Only ASCII alphanumeric or `_`. // * Must not begin with a digit. // * Must contain at least 1 character. // * <= 255 characters. let first_element_char = one_of((AsChar::is_alpha, b'_')); let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_')); let mut member_name = (first_element_char, subsequent_element_chars); member_name.parse(bytes).map_err(|_| ()).and_then(|_| { // Least likely scenario so we check this last. if bytes.len() > 255 { return Err(()); } Ok(()) }) } zbus_names-4.3.1/src/property_name.rs000064400000000000000000000033531046102023000160240ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies a [property][pn] name on the bus. /// /// # Examples /// /// ``` /// use zbus_names::PropertyName; /// /// // Valid property names. /// let name = PropertyName::try_from("Property_for_you").unwrap(); /// assert_eq!(name, "Property_for_you"); /// let name = PropertyName::try_from("CamelCase101").unwrap(); /// assert_eq!(name, "CamelCase101"); /// let name = PropertyName::try_from("a_very_loooooooooooooooooo_ooooooo_0000o0ngName").unwrap(); /// assert_eq!(name, "a_very_loooooooooooooooooo_ooooooo_0000o0ngName"); /// let name = PropertyName::try_from("Property_for_you-1").unwrap(); /// assert_eq!(name, "Property_for_you-1"); /// ``` /// /// [pn]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct PropertyName<'name>(Str<'name>); /// Owned sibling of [`PropertyName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedPropertyName(#[serde(borrow)] PropertyName<'static>); define_name_type_impls! { name: PropertyName, owned: OwnedPropertyName, validate: ensure_correct_property_name, } fn ensure_correct_property_name(name: &str) -> Result<()> { if name.is_empty() { return Err(Error::InvalidName( "Invalid property name. It has to be at least 1 character long.", )); } else if name.len() > 255 { return Err(Error::InvalidName( "Invalid property name. It can not be longer than 255 characters.", )); } Ok(()) } zbus_names-4.3.1/src/unique_name.rs000064400000000000000000000052311046102023000154430ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies a [unique bus name][ubn]. /// /// # Examples /// /// ``` /// use zbus_names::UniqueName; /// /// // Valid unique names. /// let name = UniqueName::try_from(":org.gnome.Service-for_you").unwrap(); /// assert_eq!(name, ":org.gnome.Service-for_you"); /// let name = UniqueName::try_from(":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap(); /// assert_eq!(name, ":a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name"); /// /// // Invalid unique names /// UniqueName::try_from("").unwrap_err(); /// UniqueName::try_from("dont.start.with.a.colon").unwrap_err(); /// UniqueName::try_from(":double..dots").unwrap_err(); /// UniqueName::try_from(".").unwrap_err(); /// UniqueName::try_from(".start.with.dot").unwrap_err(); /// UniqueName::try_from(":no-dots").unwrap_err(); /// ``` /// /// [ubn]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct UniqueName<'name>(pub(crate) Str<'name>); /// Owned sibling of [`UniqueName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedUniqueName(#[serde(borrow)] UniqueName<'static>); define_name_type_impls! { name: UniqueName, owned: OwnedUniqueName, validate: validate, } fn validate(name: &str) -> Result<()> { validate_bytes(name.as_bytes()).map_err(|_| { Error::InvalidName( "Invalid unique name. \ See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus" ) }) } pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> { use winnow::{ Parser, combinator::{alt, separated}, stream::AsChar, token::take_while, }; // Rules // // * Only ASCII alphanumeric, `_` or '-' // * Must begin with a `:`. // * Must contain at least one `.`. // * Each element must be 1 character (so name must be minimum 4 characters long). // * <= 255 characters. let element = take_while::<_, _, ()>(1.., (AsChar::is_alphanum, b'_', b'-')); let peer_name = (b':', (separated(2.., element, b'.'))).map(|_: (_, ())| ()); let bus_name = b"org.freedesktop.DBus".map(|_| ()); let mut unique_name = alt((bus_name, peer_name)); unique_name.parse(bytes).map_err(|_| ()).and_then(|_: ()| { // Least likely scenario so we check this last. if bytes.len() > 255 { return Err(()); } Ok(()) }) } zbus_names-4.3.1/src/utils.rs000064400000000000000000000275641046102023000143120ustar 00000000000000macro_rules! impl_str_basic { ($type:ty) => { impl zvariant::Basic for $type { const SIGNATURE_CHAR: char = >::SIGNATURE_CHAR; const SIGNATURE_STR: &'static str = >::SIGNATURE_STR; } }; } /// Generates all boilerplate code for a D-Bus name type and its owned variant. /// /// This macro generates all the boilerplate code for a D-Bus name type and its owned variant. /// /// # Parameters /// - `$name`: The name of the borrowed type (e.g., `InterfaceName`). /// - `$owned_name`: The name of the owned type (e.g., `OwnedInterfaceName`). /// - `$validate_fn`: The validation function to use. macro_rules! define_name_type_impls { ( name: $name:ident, owned: $owned_name:ident, validate: $validate_fn:ident $(,)? ) => { // === impl_str_basic for borrowed type === impl zvariant::Basic for $name<'_> { const SIGNATURE_CHAR: char = >::SIGNATURE_CHAR; const SIGNATURE_STR: &'static str = >::SIGNATURE_STR; } impl<'name> $name<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> $name<'_> { $name(self.0.as_ref()) } /// The name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new name from the given string. /// /// Since the passed string is not checked for correctness, prefer using the /// `TryFrom<&str>` implementation. pub fn from_str_unchecked(name: &'name str) -> Self { Self(zvariant::Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> crate::Result { $validate_fn(name)?; Ok(Self(zvariant::Str::from_static(name))) } /// Same as `from_str_unchecked`, except it takes a `&'static str`. pub const fn from_static_str_unchecked(name: &'static str) -> Self { Self(zvariant::Str::from_static(name)) } /// Same as `from_str_unchecked`, except it takes an owned `String`. /// /// Since the passed string is not checked for correctness, prefer using the /// `TryFrom` implementation. pub fn from_string_unchecked(name: String) -> Self { Self(zvariant::Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> $name<'static> { $name(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> $name<'static> { $name(self.0.into_owned()) } } impl std::ops::Deref for $name<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl std::borrow::Borrow for $name<'_> { fn borrow(&self) -> &str { self.as_str() } } impl std::fmt::Display for $name<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&self.as_str(), f) } } impl PartialEq for $name<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for $name<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq<$owned_name> for $name<'_> { fn eq(&self, other: &$owned_name) -> bool { *self == other.0 } } impl<'de: 'name, 'name> serde::Deserialize<'de> for $name<'name> { fn deserialize(deserializer: D) -> core::result::Result where D: serde::Deserializer<'de>, { let name = >::deserialize(deserializer)?; Self::try_from(name).map_err(|e| serde::de::Error::custom(e.to_string())) } } /// This never succeeds but is provided so it's easier to pass `Option::None` values for API /// requiring `Option>`, since type inference won't work here. impl TryFrom<()> for $name<'_> { type Error = crate::Error; fn try_from(_value: ()) -> crate::Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&$name<'name>> for $name<'name> { fn from(name: &$name<'name>) -> Self { name.clone() } } impl<'name> From<$name<'name>> for zvariant::Str<'name> { fn from(value: $name<'name>) -> Self { value.0 } } impl<'name> zvariant::NoneValue for $name<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } // === TryFrom impls for borrowed type === impl<'s> TryFrom<&'s str> for $name<'s> { type Error = crate::Error; fn try_from(value: &'s str) -> crate::Result { let value = zvariant::Str::from(value); $validate_fn(value.as_str())?; Ok(Self(value)) } } impl<'s> TryFrom<&'s str> for $owned_name { type Error = crate::Error; fn try_from(value: &'s str) -> crate::Result { Ok(Self::from(<$name<'s>>::try_from(value)?)) } } impl TryFrom for $name<'_> { type Error = crate::Error; fn try_from(value: String) -> crate::Result { let value = zvariant::Str::from(value); $validate_fn(value.as_str())?; Ok(Self(value)) } } impl TryFrom for $owned_name { type Error = crate::Error; fn try_from(value: String) -> crate::Result { Ok(Self::from(<$name<'_>>::try_from(value)?)) } } impl TryFrom> for $name<'_> { type Error = crate::Error; fn try_from(value: std::sync::Arc) -> crate::Result { let value = zvariant::Str::from(value); $validate_fn(value.as_str())?; Ok(Self(value)) } } impl TryFrom> for $owned_name { type Error = crate::Error; fn try_from(value: std::sync::Arc) -> crate::Result { Ok(Self::from(<$name<'_>>::try_from(value)?)) } } impl<'s> TryFrom> for $name<'s> { type Error = crate::Error; fn try_from(value: std::borrow::Cow<'s, str>) -> crate::Result { let value = zvariant::Str::from(value); $validate_fn(value.as_str())?; Ok(Self(value)) } } impl<'s> TryFrom> for $owned_name { type Error = crate::Error; fn try_from(value: std::borrow::Cow<'s, str>) -> crate::Result { Ok(Self::from(<$name<'s>>::try_from(value)?)) } } impl<'s> TryFrom> for $name<'s> { type Error = crate::Error; fn try_from(value: zvariant::Str<'s>) -> crate::Result { $validate_fn(value.as_str())?; Ok(Self(value)) } } impl<'s> TryFrom> for $owned_name { type Error = crate::Error; fn try_from(value: zvariant::Str<'s>) -> crate::Result { Ok(Self::from(<$name<'s>>::try_from(value)?)) } } // === Owned type impls === // impl_str_basic for owned type impl zvariant::Basic for $owned_name { const SIGNATURE_CHAR: char = >::SIGNATURE_CHAR; const SIGNATURE_STR: &'static str = >::SIGNATURE_STR; } impl $owned_name { /// Convert to the inner type, consuming `self`. pub fn into_inner(self) -> $name<'static> { self.0 } /// Get a reference to the inner type. pub fn inner(&self) -> &$name<'static> { &self.0 } /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> $name<'_> { self.0.as_ref() } } impl std::ops::Deref for $owned_name { type Target = $name<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl<'a> std::borrow::Borrow<$name<'a>> for $owned_name { fn borrow(&self) -> &$name<'a> { &self.0 } } impl std::borrow::Borrow for $owned_name { fn borrow(&self) -> &str { self.0.as_str() } } impl AsRef for $owned_name { fn as_ref(&self) -> &str { self.0.as_str() } } impl std::fmt::Debug for $owned_name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple(stringify!($owned_name)) .field(&self.as_str()) .finish() } } impl std::fmt::Display for $owned_name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&$name::from(self), f) } } impl From<$owned_name> for $name<'_> { fn from(name: $owned_name) -> Self { name.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned $owned_name> for $name<'unowned> { fn from(name: &'owned $owned_name) -> Self { $name::from_str_unchecked(name.as_str()) } } impl From<$name<'_>> for $owned_name { fn from(name: $name<'_>) -> Self { $owned_name(name.into_owned()) } } impl From<$owned_name> for zvariant::Str<'_> { fn from(value: $owned_name) -> Self { value.into_inner().0 } } impl<'de> serde::Deserialize<'de> for $owned_name { fn deserialize(deserializer: D) -> std::result::Result where D: serde::de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| { $name::try_from(n).map_err(|e| serde::de::Error::custom(e.to_string())) }) .map(Self) } } impl PartialEq<&str> for $owned_name { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq<$name<'_>> for $owned_name { fn eq(&self, other: &$name<'_>) -> bool { self.0 == *other } } impl zvariant::NoneValue for $owned_name { type NoneType = <$name<'static> as zvariant::NoneValue>::NoneType; fn null_value() -> Self::NoneType { $name::null_value() } } }; } pub(crate) use define_name_type_impls; pub(crate) use impl_str_basic; zbus_names-4.3.1/src/well_known_name.rs000064400000000000000000000056461046102023000163260ustar 00000000000000use crate::{Error, Result, utils::define_name_type_impls}; use serde::Serialize; use zvariant::{OwnedValue, Str, Type, Value}; /// String that identifies a [well-known bus name][wbn]. /// /// # Examples /// /// ``` /// use zbus_names::WellKnownName; /// /// // Valid well-known names. /// let name = WellKnownName::try_from("org.gnome.Service-for_you").unwrap(); /// assert_eq!(name, "org.gnome.Service-for_you"); /// let name = WellKnownName::try_from("a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name").unwrap(); /// assert_eq!(name, "a.very.loooooooooooooooooo-ooooooo_0000o0ng.Name"); /// /// // Invalid well-known names /// WellKnownName::try_from("").unwrap_err(); /// WellKnownName::try_from("double..dots").unwrap_err(); /// WellKnownName::try_from(".").unwrap_err(); /// WellKnownName::try_from(".start.with.dot").unwrap_err(); /// WellKnownName::try_from("1st.element.starts.with.digit").unwrap_err(); /// WellKnownName::try_from("the.2nd.element.starts.with.digit").unwrap_err(); /// WellKnownName::try_from("no-dots").unwrap_err(); /// ``` /// /// [wbn]: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus #[derive( Clone, Debug, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue, )] pub struct WellKnownName<'name>(pub(crate) Str<'name>); /// Owned sibling of [`WellKnownName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedWellKnownName(#[serde(borrow)] WellKnownName<'static>); define_name_type_impls! { name: WellKnownName, owned: OwnedWellKnownName, validate: validate, } fn validate(name: &str) -> Result<()> { validate_bytes(name.as_bytes()).map_err(|_| { Error::InvalidName( "Invalid well-known name. \ See https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus" ) }) } pub(crate) fn validate_bytes(bytes: &[u8]) -> std::result::Result<(), ()> { use winnow::{ Parser, combinator::separated, stream::AsChar, token::{one_of, take_while}, }; // Rules // // * Only ASCII alphanumeric, `_` or '-'. // * Must not begin with a `.`. // * Must contain at least one `.`. // * Each element must: // * not begin with a digit. // * be 1 character (so name must be minimum 3 characters long). // * <= 255 characters. let first_element_char = one_of((AsChar::is_alpha, b'_', b'-')); let subsequent_element_chars = take_while::<_, _, ()>(0.., (AsChar::is_alphanum, b'_', b'-')); let element = (first_element_char, subsequent_element_chars); let mut well_known_name = separated(2.., element, b'.'); well_known_name .parse(bytes) .map_err(|_| ()) .and_then(|_: ()| { // Least likely scenario so we check this last. if bytes.len() > 255 { return Err(()); } Ok(()) }) }