#[macro_export]
macro_rules! lit_str {
($struct_name:ident, $val:expr) => {
#[doc = concat!("A unit struct representing the string literal \"", $val, "\".")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct $struct_name;
impl $struct_name {
pub const VALUE: &'static str = $val;
}
impl AsRef<str> for $struct_name {
fn as_ref(&self) -> &str {
Self::VALUE
}
}
impl std::str::FromStr for $struct_name {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == Self::VALUE {
Ok($struct_name)
} else {
Err(format!("expected '{}', got '{}'", Self::VALUE, s))
}
}
}
impl serde::Serialize for $struct_name {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(Self::VALUE)
}
}
impl<'de> serde::Deserialize<'de> for $struct_name {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
if s == Self::VALUE {
Ok($struct_name)
} else {
Err(serde::de::Error::custom(format!(
"expected '{}', got '{}'",
Self::VALUE,
s
)))
}
}
}
impl std::fmt::Display for $struct_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, $val)
}
}
};
}