zbus_names-3.0.0/.cargo_vcs_info.json0000644000000001500000000000100131760ustar { "git": { "sha1": "25876f399b068749c337374505c35e92dc9e5872" }, "path_in_vcs": "zbus_names" }zbus_names-3.0.0/Cargo.toml0000644000000021370000000000100112030ustar # 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" rust-version = "1.75" name = "zbus_names" version = "3.0.0" authors = ["Zeeshan Ali Khan "] 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/dbus2/zbus/" [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] [dependencies.serde] version = "1.0" features = ["derive"] [dependencies.static_assertions] version = "1.1.0" [dependencies.zvariant] version = "4.0.0" features = ["enumflags2"] default-features = false zbus_names-3.0.0/Cargo.toml.orig000064400000000000000000000012021046102023000146540ustar 00000000000000[package] name = "zbus_names" version = "3.0.0" authors = ["Zeeshan Ali Khan "] edition = "2021" rust-version = "1.75" description = "A collection of D-Bus bus names types" repository = "https://github.com/dbus2/zbus/" keywords = ["D-Bus", "DBus", "IPC"] license = "MIT" categories = ["os::unix-apis"] readme = "README.md" [dependencies] serde = { version = "1.0", features = ["derive"] } zvariant = { path = "../zvariant", version = "4.0.0", default-features = false, features = [ "enumflags2", ] } static_assertions = "1.1.0" [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] zbus_names-3.0.0/LICENSE000064400000000000000000000017771046102023000130130ustar 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_names-3.0.0/README.md000064400000000000000000000013721046102023000132540ustar 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-3.0.0/src/bus_name.rs000064400000000000000000000332331046102023000147240ustar 00000000000000use core::{ borrow::Borrow, fmt::{self, Debug, Display, Formatter}, ops::Deref, }; use std::{borrow::Cow, sync::Arc}; use crate::{ utils::impl_str_basic, Error, OwnedUniqueName, OwnedWellKnownName, Result, UniqueName, WellKnownName, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; 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>), } assert_impl_all!(BusName<'_>: Send, Sync, Unpin); impl_str_basic!(BusName<'_>); impl<'name> BusName<'name> { /// 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<'_> { fn signature() -> zvariant::Signature<'static> { <&str>::signature() } } 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 { match UniqueName::try_from(value.clone()) { Err(Error::InvalidUniqueName(unique_err)) => match WellKnownName::try_from(value) { Err(Error::InvalidWellKnownName(well_known_err)) => { Err(Error::InvalidBusName(unique_err, well_known_err)) } Err(e) => Err(e), Ok(name) => Ok(BusName::WellKnown(name)), }, Err(e) => Err(e), Ok(name) => Ok(BusName::Unique(name)), } } } impl<'s> TryFrom<&'s str> for BusName<'s> { type Error = Error; fn try_from(value: &'s str) -> Result { Str::from(value).try_into() } } impl<'s> TryFrom for BusName<'s> { type Error = Error; fn try_from(value: String) -> Result { Str::from(value).try_into() } } impl<'s> TryFrom> for BusName<'s> { 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 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() } } zbus_names-3.0.0/src/error.rs000064400000000000000000000067141046102023000142700ustar 00000000000000use static_assertions::assert_impl_all; use 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. InvalidBusName(String, String), /// Invalid well-known bus name. InvalidWellKnownName(String), /// Invalid unique bus name. InvalidUniqueName(String), /// Invalid interface name. InvalidInterfaceName(String), /// Invalid member (method or signal) name. InvalidMemberName(String), /// Invalid property name. InvalidPropertyName(String), /// Invalid error name. InvalidErrorName(String), } assert_impl_all!(Error: Send, Sync, Unpin); impl PartialEq for Error { 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::Variant(s), Self::Variant(o)) => s == o, (_, _) => false, } } } impl error::Error for Error { 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::Variant(e) => Some(e), } } } impl fmt::Display for Error { 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}"), } } } 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-3.0.0/src/error_name.rs000064400000000000000000000226441046102023000152700ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, OwnedValue, Str, Type, Value}; /// String that identifies an [error name][en] on the bus. /// /// Error names have same constraints as error 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>); assert_impl_all!(ErrorName<'_>: Send, Sync, Unpin); impl_str_basic!(ErrorName<'_>); impl<'name> ErrorName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> ErrorName<'_> { ErrorName(self.0.as_ref()) } /// The error name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `ErrorName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_error_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> ErrorName<'static> { ErrorName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> ErrorName<'static> { ErrorName(self.0.into_owned()) } } impl Deref for ErrorName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for ErrorName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for ErrorName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for ErrorName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for ErrorName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for ErrorName<'_> { fn eq(&self, other: &OwnedErrorName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for ErrorName<'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_try_from! { ty: ErrorName<'s>, owned_ty: OwnedErrorName, validate_fn: ensure_correct_error_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } fn ensure_correct_error_name(name: &str) -> Result<()> { // 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. if name.len() < 3 { return Err(Error::InvalidErrorName(format!( "`{}` is {} characters long, which is smaller than minimum allowed (3)", name, name.len(), ))); } else if name.len() > 255 { return Err(Error::InvalidErrorName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } let mut prev = None; let mut no_dot = true; for c in name.chars() { if c == '.' { if prev.is_none() || prev == Some('.') { return Err(Error::InvalidErrorName(String::from( "must not contain a double `.`", ))); } if no_dot { no_dot = false; } } else if c.is_ascii_digit() && (prev.is_none() || prev == Some('.')) { return Err(Error::InvalidErrorName(String::from( "each element must not start with a digit", ))); } else if !c.is_ascii_alphanumeric() && c != '_' { return Err(Error::InvalidErrorName(format!( "`{c}` character not allowed" ))); } prev = Some(c); } if no_dot { return Err(Error::InvalidErrorName(String::from( "must contain at least 1 `.`", ))); } Ok(()) } /// 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 ErrorName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&ErrorName<'name>> for ErrorName<'name> { fn from(name: &ErrorName<'name>) -> Self { name.clone() } } impl<'name> From> for Str<'name> { fn from(value: ErrorName<'name>) -> Self { value.0 } } impl<'name> NoneValue for ErrorName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`ErrorName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedErrorName(#[serde(borrow)] ErrorName<'static>); assert_impl_all!(OwnedErrorName: Send, Sync, Unpin); impl_str_basic!(OwnedErrorName); impl OwnedErrorName { /// Convert to the inner `ErrorName`, consuming `self`. pub fn into_inner(self) -> ErrorName<'static> { self.0 } /// Get a reference to the inner `ErrorName`. pub fn inner(&self) -> &ErrorName<'static> { &self.0 } } impl Deref for OwnedErrorName { type Target = ErrorName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedErrorName { fn borrow(&self) -> &str { self.0.as_str() } } impl From for ErrorName<'_> { fn from(o: OwnedErrorName) -> Self { o.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedErrorName> for ErrorName<'unowned> { fn from(name: &'owned OwnedErrorName) -> Self { ErrorName::from_str_unchecked(name.as_str()) } } impl From> for OwnedErrorName { fn from(name: ErrorName<'_>) -> Self { OwnedErrorName(name.into_owned()) } } impl From for Str<'_> { fn from(value: OwnedErrorName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedErrorName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| ErrorName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedErrorName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedErrorName { fn eq(&self, other: &ErrorName<'_>) -> bool { self.0 == *other } } impl Debug for OwnedErrorName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedErrorName") .field(&self.as_str()) .finish() } } impl Display for OwnedErrorName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&ErrorName::from(self), f) } } impl NoneValue for OwnedErrorName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { ErrorName::null_value() } } zbus_names-3.0.0/src/interface_name.rs000064400000000000000000000233371046102023000160770ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, 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>); impl_str_basic!(InterfaceName<'_>); assert_impl_all!(InterfaceName<'_>: Send, Sync, Unpin); impl<'name> InterfaceName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> InterfaceName<'_> { InterfaceName(self.0.as_ref()) } /// The interface name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `InterfaceName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_interface_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> InterfaceName<'static> { InterfaceName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> InterfaceName<'static> { InterfaceName(self.0.into_owned()) } } impl Deref for InterfaceName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for InterfaceName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for InterfaceName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for InterfaceName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for InterfaceName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for InterfaceName<'_> { fn eq(&self, other: &OwnedInterfaceName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for InterfaceName<'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_try_from! { ty:InterfaceName<'s>, owned_ty: OwnedInterfaceName, validate_fn: ensure_correct_interface_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } impl<'name> From> for Str<'name> { fn from(value: InterfaceName<'name>) -> Self { value.0 } } fn ensure_correct_interface_name(name: &str) -> Result<()> { // 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. if name.len() < 3 { return Err(Error::InvalidInterfaceName(format!( "`{}` is {} characters long, which is smaller than minimum allowed (3)", name, name.len(), ))); } else if name.len() > 255 { return Err(Error::InvalidInterfaceName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } let mut prev = None; let mut no_dot = true; for c in name.chars() { if c == '.' { if prev.is_none() || prev == Some('.') { return Err(Error::InvalidInterfaceName(String::from( "must not contain a double `.`", ))); } if no_dot { no_dot = false; } } else if c.is_ascii_digit() && (prev.is_none() || prev == Some('.')) { return Err(Error::InvalidInterfaceName(String::from( "each element must not start with a digit", ))); } else if !c.is_ascii_alphanumeric() && c != '_' { return Err(Error::InvalidInterfaceName(format!( "`{c}` character not allowed" ))); } prev = Some(c); } if no_dot { return Err(Error::InvalidInterfaceName(String::from( "must contain at least 1 `.`", ))); } Ok(()) } /// 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 InterfaceName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&InterfaceName<'name>> for InterfaceName<'name> { fn from(name: &InterfaceName<'name>) -> Self { name.clone() } } impl<'name> NoneValue for InterfaceName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`InterfaceName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedInterfaceName(#[serde(borrow)] InterfaceName<'static>); assert_impl_all!(OwnedInterfaceName: Send, Sync, Unpin); impl_str_basic!(OwnedInterfaceName); impl OwnedInterfaceName { /// Convert to the inner `InterfaceName`, consuming `self`. pub fn into_inner(self) -> InterfaceName<'static> { self.0 } /// Get a reference to the inner `InterfaceName`. pub fn inner(&self) -> &InterfaceName<'static> { &self.0 } } impl Deref for OwnedInterfaceName { type Target = InterfaceName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedInterfaceName { fn borrow(&self) -> &str { self.0.as_str() } } impl From for InterfaceName<'_> { fn from(o: OwnedInterfaceName) -> Self { o.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedInterfaceName> for InterfaceName<'unowned> { fn from(name: &'owned OwnedInterfaceName) -> Self { InterfaceName::from_str_unchecked(name.as_str()) } } impl From> for OwnedInterfaceName { fn from(name: InterfaceName<'_>) -> Self { OwnedInterfaceName(name.into_owned()) } } impl From for Str<'_> { fn from(value: OwnedInterfaceName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedInterfaceName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| InterfaceName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedInterfaceName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedInterfaceName { fn eq(&self, other: &InterfaceName<'_>) -> bool { self.0 == *other } } impl Debug for OwnedInterfaceName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedInterfaceName") .field(&self.as_str()) .finish() } } impl Display for OwnedInterfaceName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&InterfaceName::from(self), f) } } impl NoneValue for OwnedInterfaceName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { InterfaceName::null_value() } } zbus_names-3.0.0/src/lib.rs000064400000000000000000000013011046102023000136700ustar 00000000000000#![deny(rust_2018_idioms)] #![doc( html_logo_url = "https://storage.googleapis.com/fdo-gitlab-uploads/project/avatar/3213/zbus-logomark.png" )] #![doc = include_str!("../README.md")] #![doc(test(attr( warn(unused), deny(warnings), // 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-3.0.0/src/member_name.rs000064400000000000000000000213241046102023000154000ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, 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>); assert_impl_all!(MemberName<'_>: Send, Sync, Unpin); impl_str_basic!(MemberName<'_>); impl<'name> MemberName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> MemberName<'_> { MemberName(self.0.as_ref()) } /// The member name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `MemberName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_member_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> MemberName<'static> { MemberName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> MemberName<'static> { MemberName(self.0.into_owned()) } } impl Deref for MemberName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for MemberName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for MemberName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for MemberName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for MemberName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for MemberName<'_> { fn eq(&self, other: &OwnedMemberName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for MemberName<'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<'name> From> for Str<'name> { fn from(value: MemberName<'name>) -> Self { value.0 } } impl_try_from! { ty: MemberName<'s>, owned_ty: OwnedMemberName, validate_fn: ensure_correct_member_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } fn ensure_correct_member_name(name: &str) -> Result<()> { // Rules // // * Only ASCII alphanumeric or `_`. // * Must not begin with a digit. // * Must contain at least 1 character. // * <= 255 characters. if name.is_empty() { return Err(Error::InvalidMemberName(format!( "`{}` is {} characters long, which is smaller than minimum allowed (1)", name, name.len(), ))); } else if name.len() > 255 { return Err(Error::InvalidMemberName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } // SAFETY: We established above that there is at least 1 character so unwrap is fine. if name.chars().next().unwrap().is_ascii_digit() { return Err(Error::InvalidMemberName(String::from( "must not start with a digit", ))); } for c in name.chars() { if !c.is_ascii_alphanumeric() && c != '_' { return Err(Error::InvalidMemberName(format!( "`{c}` character not allowed" ))); } } Ok(()) } /// 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 MemberName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&MemberName<'name>> for MemberName<'name> { fn from(name: &MemberName<'name>) -> Self { name.clone() } } impl<'name> NoneValue for MemberName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`MemberName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedMemberName(#[serde(borrow)] MemberName<'static>); assert_impl_all!(OwnedMemberName: Send, Sync, Unpin); impl_str_basic!(OwnedMemberName); impl OwnedMemberName { /// Convert to the inner `MemberName`, consuming `self`. pub fn into_inner(self) -> MemberName<'static> { self.0 } /// Get a reference to the inner `MemberName`. pub fn inner(&self) -> &MemberName<'static> { &self.0 } } impl Deref for OwnedMemberName { type Target = MemberName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedMemberName { fn borrow(&self) -> &str { self.0.as_str() } } impl From for MemberName<'_> { fn from(o: OwnedMemberName) -> Self { o.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedMemberName> for MemberName<'unowned> { fn from(name: &'owned OwnedMemberName) -> Self { MemberName::from_str_unchecked(name.as_str()) } } impl From> for OwnedMemberName { fn from(name: MemberName<'_>) -> Self { OwnedMemberName(name.into_owned()) } } impl From for Str<'_> { fn from(value: OwnedMemberName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedMemberName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| MemberName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedMemberName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedMemberName { fn eq(&self, other: &MemberName<'_>) -> bool { self.0 == *other } } impl Debug for OwnedMemberName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedMemberName") .field(&self.as_str()) .finish() } } impl Display for OwnedMemberName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&MemberName::from(self), f) } } impl NoneValue for OwnedMemberName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { MemberName::null_value() } } zbus_names-3.0.0/src/property_name.rs000064400000000000000000000202561046102023000160200ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, 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>); assert_impl_all!(PropertyName<'_>: Send, Sync, Unpin); impl_str_basic!(PropertyName<'_>); impl<'name> PropertyName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> PropertyName<'_> { PropertyName(self.0.as_ref()) } /// The property name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `PropertyName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_property_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> PropertyName<'static> { PropertyName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> PropertyName<'static> { PropertyName(self.0.into_owned()) } } impl Deref for PropertyName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for PropertyName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for PropertyName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for PropertyName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for PropertyName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for PropertyName<'_> { fn eq(&self, other: &OwnedPropertyName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for PropertyName<'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<'name> From> for Str<'name> { fn from(value: PropertyName<'name>) -> Self { value.0 } } impl_try_from! { ty: PropertyName<'s>, owned_ty: OwnedPropertyName, validate_fn: ensure_correct_property_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } fn ensure_correct_property_name(name: &str) -> Result<()> { // Rules // // * Only ASCII alphanumeric or `_`. // * Must not begin with a digit. // * Must contain at least 1 character. // * <= 255 characters. if name.is_empty() { return Err(Error::InvalidPropertyName(format!( "`{}` is {} characters long, which is smaller than minimum allowed (1)", name, name.len(), ))); } else if name.len() > 255 { return Err(Error::InvalidPropertyName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } Ok(()) } /// 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 PropertyName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&PropertyName<'name>> for PropertyName<'name> { fn from(name: &PropertyName<'name>) -> Self { name.clone() } } impl<'name> NoneValue for PropertyName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`PropertyName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedPropertyName(#[serde(borrow)] PropertyName<'static>); assert_impl_all!(OwnedPropertyName: Send, Sync, Unpin); impl_str_basic!(OwnedPropertyName); impl OwnedPropertyName { /// Convert to the inner `PropertyName`, consuming `self`. pub fn into_inner(self) -> PropertyName<'static> { self.0 } /// Get a reference to the inner `PropertyName`. pub fn inner(&self) -> &PropertyName<'static> { &self.0 } } impl Deref for OwnedPropertyName { type Target = PropertyName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedPropertyName { fn borrow(&self) -> &str { self.0.as_str() } } impl From for PropertyName<'_> { fn from(o: OwnedPropertyName) -> Self { o.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedPropertyName> for PropertyName<'unowned> { fn from(name: &'owned OwnedPropertyName) -> Self { PropertyName::from_str_unchecked(name.as_str()) } } impl From> for OwnedPropertyName { fn from(name: PropertyName<'_>) -> Self { OwnedPropertyName(name.into_owned()) } } impl From for Str<'_> { fn from(value: OwnedPropertyName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedPropertyName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| PropertyName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedPropertyName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedPropertyName { fn eq(&self, other: &PropertyName<'_>) -> bool { self.0 == *other } } impl Debug for OwnedPropertyName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedPropertyName") .field(&self.as_str()) .finish() } } impl Display for OwnedPropertyName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&PropertyName::from(self), f) } } impl NoneValue for OwnedPropertyName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { PropertyName::null_value() } } zbus_names-3.0.0/src/unique_name.rs000064400000000000000000000223641046102023000154440ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, 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>(Str<'name>); assert_impl_all!(UniqueName<'_>: Send, Sync, Unpin); impl_str_basic!(UniqueName<'_>); impl<'name> UniqueName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> UniqueName<'_> { UniqueName(self.0.as_ref()) } /// The unique name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `UniqueName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_unique_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> UniqueName<'static> { UniqueName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> UniqueName<'static> { UniqueName(self.0.into_owned()) } } impl Deref for UniqueName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for UniqueName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for UniqueName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl PartialEq for UniqueName<'_> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl PartialEq<&str> for UniqueName<'_> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for UniqueName<'_> { fn eq(&self, other: &OwnedUniqueName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for UniqueName<'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())) } } fn ensure_correct_unique_name(name: &str) -> Result<()> { // Rules // // * Only ASCII alphanumeric, `_` or '-' // * Must begin with a `:`. // * Must contain at least one `.`. // * <= 255 characters. if name.is_empty() { return Err(Error::InvalidUniqueName(String::from( "must contain at least 4 characters", ))); } else if name.len() > 255 { return Err(Error::InvalidUniqueName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } else if name == "org.freedesktop.DBus" { // Bus itself uses its well-known name as its unique name. return Ok(()); } // SAFETY: Just checked above that we've at least 1 character. let mut chars = name.chars(); let mut prev = match chars.next().expect("no first char") { first @ ':' => first, _ => { return Err(Error::InvalidUniqueName(String::from( "must start with a `:`", ))); } }; let mut no_dot = true; for c in chars { if c == '.' { if prev == '.' { return Err(Error::InvalidUniqueName(String::from( "must not contain a double `.`", ))); } if no_dot { no_dot = false; } } else if !c.is_ascii_alphanumeric() && c != '_' && c != '-' { return Err(Error::InvalidUniqueName(format!( "`{c}` character not allowed" ))); } prev = c; } if no_dot { return Err(Error::InvalidUniqueName(String::from( "must contain at least 1 `.`", ))); } Ok(()) } /// 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 UniqueName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&UniqueName<'name>> for UniqueName<'name> { fn from(name: &UniqueName<'name>) -> Self { name.clone() } } impl<'name> From> for Str<'name> { fn from(value: UniqueName<'name>) -> Self { value.0 } } impl<'name> NoneValue for UniqueName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`UniqueName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedUniqueName(#[serde(borrow)] UniqueName<'static>); assert_impl_all!(OwnedUniqueName: Send, Sync, Unpin); impl_str_basic!(OwnedUniqueName); impl OwnedUniqueName { /// Convert to the inner `UniqueName`, consuming `self`. pub fn into_inner(self) -> UniqueName<'static> { self.0 } /// Get a reference to the inner `UniqueName`. pub fn inner(&self) -> &UniqueName<'static> { &self.0 } } impl Deref for OwnedUniqueName { type Target = UniqueName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedUniqueName { fn borrow(&self) -> &str { self.0.as_str() } } impl From for UniqueName<'_> { fn from(o: OwnedUniqueName) -> Self { o.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedUniqueName> for UniqueName<'unowned> { fn from(name: &'owned OwnedUniqueName) -> Self { UniqueName::from_str_unchecked(name.as_str()) } } impl From> for OwnedUniqueName { fn from(name: UniqueName<'_>) -> Self { OwnedUniqueName(name.into_owned()) } } impl_try_from! { ty: UniqueName<'s>, owned_ty: OwnedUniqueName, validate_fn: ensure_correct_unique_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } impl From for Str<'_> { fn from(value: OwnedUniqueName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedUniqueName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| UniqueName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedUniqueName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedUniqueName { fn eq(&self, other: &UniqueName<'_>) -> bool { self.0 == *other } } impl NoneValue for OwnedUniqueName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { UniqueName::null_value() } } impl Debug for OwnedUniqueName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedUniqueName") .field(&self.as_str()) .finish() } } impl Display for OwnedUniqueName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&UniqueName::from(self), f) } } zbus_names-3.0.0/src/utils.rs000064400000000000000000000022721046102023000142720ustar 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; fn alignment(format: zvariant::serialized::Format) -> usize { >::alignment(format) } } }; } macro_rules! impl_try_from { (ty: $type:ty, owned_ty: $owned_type:ty, validate_fn: $validate_fn:ident, try_from: [$($from:ty),*],) => { $( impl<'s> TryFrom<$from> for $type { type Error = Error; fn try_from(value: $from) -> Result { let value = Str::from(value); $validate_fn(value.as_str())?; Ok(Self(value)) } } impl<'s> TryFrom<$from> for $owned_type { type Error = Error; fn try_from(value: $from) -> Result { Ok(Self::from(<$type>::try_from(value)?)) } } )* }; } pub(crate) use impl_str_basic; pub(crate) use impl_try_from; zbus_names-3.0.0/src/well_known_name.rs000064400000000000000000000235571046102023000163220ustar 00000000000000use crate::{ utils::{impl_str_basic, impl_try_from}, Error, Result, }; use serde::{de, Deserialize, Serialize}; use static_assertions::assert_impl_all; use std::{ borrow::{Borrow, Cow}, fmt::{self, Debug, Display, Formatter}, ops::Deref, sync::Arc, }; use zvariant::{NoneValue, 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>(Str<'name>); impl_str_basic!(WellKnownName<'_>); assert_impl_all!(WellKnownName<'_>: Send, Sync, Unpin); impl<'name> WellKnownName<'name> { /// This is faster than `Clone::clone` when `self` contains owned data. pub fn as_ref(&self) -> WellKnownName<'_> { WellKnownName(self.0.as_ref()) } /// The well-known-name as string. pub fn as_str(&self) -> &str { self.0.as_str() } /// Create a new `WellKnownName` 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(Str::from(name)) } /// Same as `try_from`, except it takes a `&'static str`. pub fn from_static_str(name: &'static str) -> Result { ensure_correct_well_known_name(name)?; Ok(Self(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(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(Str::from(name)) } /// Creates an owned clone of `self`. pub fn to_owned(&self) -> WellKnownName<'static> { WellKnownName(self.0.to_owned()) } /// Creates an owned clone of `self`. pub fn into_owned(self) -> WellKnownName<'static> { WellKnownName(self.0.into_owned()) } } impl Deref for WellKnownName<'_> { type Target = str; fn deref(&self) -> &Self::Target { self.as_str() } } impl Borrow for WellKnownName<'_> { fn borrow(&self) -> &str { self.as_str() } } impl Display for WellKnownName<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&self.as_str(), f) } } impl<'a> PartialEq for WellKnownName<'a> { fn eq(&self, other: &str) -> bool { self.as_str() == other } } impl<'a> PartialEq<&str> for WellKnownName<'a> { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq for WellKnownName<'_> { fn eq(&self, other: &OwnedWellKnownName) -> bool { *self == other.0 } } impl<'de: 'name, 'name> Deserialize<'de> for WellKnownName<'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())) } } fn ensure_correct_well_known_name(name: &str) -> Result<()> { // 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. if name.is_empty() { return Err(Error::InvalidWellKnownName(String::from( "must contain at least 3 characters", ))); } else if name.len() < 3 { return Err(Error::InvalidWellKnownName(format!( "`{}` is {} characters long, which is smaller than minimum allowed (3)", name, name.len(), ))); } else if name.len() > 255 { return Err(Error::InvalidWellKnownName(format!( "`{}` is {} characters long, which is longer than maximum allowed (255)", name, name.len(), ))); } let mut prev = None; let mut no_dot = true; for c in name.chars() { if c == '.' { if prev.is_none() || prev == Some('.') { return Err(Error::InvalidWellKnownName(String::from( "must not contain a double `.`", ))); } if no_dot { no_dot = false; } } else if c.is_ascii_digit() && (prev.is_none() || prev == Some('.')) { return Err(Error::InvalidWellKnownName(String::from( "each element must not start with a digit", ))); } else if !c.is_ascii_alphanumeric() && c != '_' && c != '-' { return Err(Error::InvalidWellKnownName(format!( "`{c}` character not allowed" ))); } prev = Some(c); } if no_dot { return Err(Error::InvalidWellKnownName(String::from( "must contain at least 1 `.`", ))); } Ok(()) } /// 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 WellKnownName<'_> { type Error = Error; fn try_from(_value: ()) -> Result { unreachable!("Conversion from `()` is not meant to actually work"); } } impl<'name> From<&WellKnownName<'name>> for WellKnownName<'name> { fn from(name: &WellKnownName<'name>) -> Self { name.clone() } } impl<'name> From> for Str<'name> { fn from(value: WellKnownName<'name>) -> Self { value.0 } } impl<'name> NoneValue for WellKnownName<'name> { type NoneType = &'name str; fn null_value() -> Self::NoneType { <&str>::default() } } /// Owned sibling of [`WellKnownName`]. #[derive(Clone, Hash, PartialEq, Eq, Serialize, Type, Value, PartialOrd, Ord, OwnedValue)] pub struct OwnedWellKnownName(#[serde(borrow)] WellKnownName<'static>); assert_impl_all!(OwnedWellKnownName: Send, Sync, Unpin); impl OwnedWellKnownName { /// Convert to the inner `WellKnownName`, consuming `self`. pub fn into_inner(self) -> WellKnownName<'static> { self.0 } /// Get a reference to the inner `WellKnownName`. pub fn inner(&self) -> &WellKnownName<'static> { &self.0 } } impl_str_basic!(OwnedWellKnownName); impl Deref for OwnedWellKnownName { type Target = WellKnownName<'static>; fn deref(&self) -> &Self::Target { &self.0 } } impl Borrow for OwnedWellKnownName { fn borrow(&self) -> &str { self.0.as_str() } } impl AsRef for OwnedWellKnownName { fn as_ref(&self) -> &str { self.0.as_str() } } impl Debug for OwnedWellKnownName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_tuple("OwnedWellKnownName") .field(&self.as_str()) .finish() } } impl Display for OwnedWellKnownName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(&WellKnownName::from(self), f) } } impl From for WellKnownName<'_> { fn from(name: OwnedWellKnownName) -> Self { name.into_inner() } } impl<'unowned, 'owned: 'unowned> From<&'owned OwnedWellKnownName> for WellKnownName<'unowned> { fn from(name: &'owned OwnedWellKnownName) -> Self { WellKnownName::from_str_unchecked(name.as_str()) } } impl From> for OwnedWellKnownName { fn from(name: WellKnownName<'_>) -> Self { OwnedWellKnownName(name.into_owned()) } } impl_try_from! { ty: WellKnownName<'s>, owned_ty: OwnedWellKnownName, validate_fn: ensure_correct_well_known_name, try_from: [&'s str, String, Arc, Cow<'s, str>, Str<'s>], } impl From for Str<'_> { fn from(value: OwnedWellKnownName) -> Self { value.into_inner().0 } } impl<'de> Deserialize<'de> for OwnedWellKnownName { fn deserialize(deserializer: D) -> std::result::Result where D: de::Deserializer<'de>, { String::deserialize(deserializer) .and_then(|n| WellKnownName::try_from(n).map_err(|e| de::Error::custom(e.to_string()))) .map(Self) } } impl PartialEq<&str> for OwnedWellKnownName { fn eq(&self, other: &&str) -> bool { self.as_str() == *other } } impl PartialEq> for OwnedWellKnownName { fn eq(&self, other: &WellKnownName<'_>) -> bool { self.0 == *other } } impl NoneValue for OwnedWellKnownName { type NoneType = as NoneValue>::NoneType; fn null_value() -> Self::NoneType { WellKnownName::null_value() } }