use alloc::{string::String, vec::Vec}; use core::fmt; use serde::de::{Deserializer, Error, Unexpected, Visitor}; use serde_core as serde; use crate::SmolStr; // https://github.com/serde-rs/serde/blob/629802f2abfd1a54a6072992888fea7ca5bc209f/serde/src/private/de.rs#L56-L125 fn smol_str<'de: 'a, 'a, D>(deserializer: D) -> Result where D: Deserializer<'de>, { struct SmolStrVisitor; impl<'a> Visitor<'a> for SmolStrVisitor { type Value = SmolStr; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a string") } fn visit_str(self, v: &str) -> Result where E: Error, { Ok(SmolStr::from(v)) } fn visit_borrowed_str(self, v: &'a str) -> Result where E: Error, { Ok(SmolStr::from(v)) } fn visit_string(self, v: String) -> Result where E: Error, { Ok(SmolStr::from(v)) } fn visit_bytes(self, v: &[u8]) -> Result where E: Error, { match core::str::from_utf8(v) { Ok(s) => Ok(SmolStr::from(s)), Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), } } fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result where E: Error, { match core::str::from_utf8(v) { Ok(s) => Ok(SmolStr::from(s)), Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), } } fn visit_byte_buf(self, v: Vec) -> Result where E: Error, { match String::from_utf8(v) { Ok(s) => Ok(SmolStr::from(s)), Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), } } } deserializer.deserialize_str(SmolStrVisitor) } impl serde::Serialize for SmolStr { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { self.as_str().serialize(serializer) } } impl<'de> serde::Deserialize<'de> for SmolStr { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { smol_str(deserializer) } }