use std::{borrow::Cow, fmt};
use compact_str::CompactString;
use serde::{
Deserialize, Deserializer, Serialize, Serializer,
de::{self, Visitor},
};
#[derive(Clone, PartialEq, Eq)]
pub(crate) struct Name(CompactString);
impl Name {
pub(crate) fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl From<&str> for Name {
fn from(text: &str) -> Self {
Self(CompactString::from(text))
}
}
impl From<String> for Name {
fn from(text: String) -> Self {
Self(CompactString::from(text))
}
}
impl From<Cow<'_, str>> for Name {
fn from(text: Cow<'_, str>) -> Self {
match text {
Cow::Borrowed(text) => Self::from(text),
Cow::Owned(text) => Self::from(text),
}
}
}
impl fmt::Debug for Name {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_str(), formatter)
}
}
impl Serialize for Name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for Name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(NameVisitor)
}
}
struct NameVisitor;
impl Visitor<'_> for NameVisitor {
type Value = Name;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E: de::Error>(self, value: &str) -> Result<Name, E> {
Ok(Name::from(value))
}
fn visit_string<E: de::Error>(self, value: String) -> Result<Name, E> {
Ok(Name::from(value))
}
}
#[cfg(test)]
#[path = "name_tests.rs"]
mod tests;