use std::{borrow::Cow, fmt};
use serde::{
Deserialize, Deserializer,
de::{self, Visitor},
};
#[derive(PartialEq, Eq, Hash, Debug)]
pub struct CowStr<'de>(Cow<'de, str>);
impl<'de> CowStr<'de> {
pub fn into_inner(self) -> Cow<'de, str> {
self.0
}
}
impl<'de> Deserialize<'de> for CowStr<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(CowStrVisitor)
}
}
struct CowStrVisitor;
impl<'de> Visitor<'de> for CowStrVisitor {
type Value = CowStr<'de>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(CowStr(Cow::Borrowed(value)))
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(CowStr(Cow::Owned(value.to_owned())))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(CowStr(Cow::Owned(value)))
}
}