/// Declares an item with a doc attribute computed by some macro expression. /// This allows documentation to be dynamically generated based on input. /// Necessary to work around https://github.com/rust-lang/rust/issues/52607. macro_rules! doc_concat { ( $( #[doc = $doc:expr] $thing:item )* ) => ( $( #[doc = $doc] $thing )* ); } macro_rules! common_impls { ($id:ident, $try_from:ident, $desc:literal) => { impl> $id { doc_concat! { #[doc = concat!("Creates a string slice from this `", stringify!($id), "`")] pub fn as_str(&self) -> &str { self.full_id.as_ref() } } } impl<'a> ::std::convert::From<&'a $id>> for $id<&'a str> { fn from(id: &'a $id>) -> Self { id.as_ref() } } impl ::std::convert::From<$id>> for ::std::string::String { fn from(id: $id>) -> Self { id.full_id.into() } } impl<'a> ::std::convert::TryFrom<&'a str> for $id<&'a str> { type Error = crate::error::Error; fn try_from(s: &'a str) -> Result { $try_from(s) } } impl ::std::convert::TryFrom<&str> for $id> { type Error = crate::error::Error; fn try_from(s: &str) -> Result { $try_from(s) } } impl ::std::convert::TryFrom for $id> { type Error = crate::error::Error; fn try_from(s: String) -> Result { $try_from(s) } } impl> ::std::convert::AsRef for $id { fn as_ref(&self) -> &str { self.full_id.as_ref() } } impl ::std::fmt::Display for $id { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { write!(f, "{}", self.full_id) } } impl ::std::cmp::PartialEq for $id { fn eq(&self, other: &Self) -> bool { self.full_id == other.full_id } } impl ::std::cmp::Eq for $id {} impl ::std::cmp::PartialOrd for $id { fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> { ::std::cmp::PartialOrd::partial_cmp(&self.full_id, &other.full_id) } } impl ::std::cmp::Ord for $id { fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { ::std::cmp::Ord::cmp(&self.full_id, &other.full_id) } } impl ::std::hash::Hash for $id { fn hash(&self, state: &mut H) { self.full_id.hash(state); } } #[cfg(feature = "serde")] impl> ::serde::Serialize for $id { fn serialize(&self, serializer: S) -> Result where S: ::serde::Serializer, { serializer.serialize_str(self.full_id.as_ref()) } } #[cfg(feature = "serde")] impl<'de> ::serde::Deserialize<'de> for $id> { fn deserialize(deserializer: D) -> Result where D: ::serde::Deserializer<'de>, { crate::deserialize_id(deserializer, $desc) } } impl> ::std::cmp::PartialEq<&str> for $id { fn eq(&self, other: &&str) -> bool { self.full_id.as_ref() == *other } } impl> ::std::cmp::PartialEq<$id> for &str { fn eq(&self, other: &$id) -> bool { *self == other.full_id.as_ref() } } impl> ::std::cmp::PartialEq<::std::string::String> for $id { fn eq(&self, other: &::std::string::String) -> bool { self.full_id.as_ref() == &other[..] } } impl> ::std::cmp::PartialEq<$id> for ::std::string::String { fn eq(&self, other: &$id) -> bool { &self[..] == other.full_id.as_ref() } } }; }