use super::utils::FromCDataVisitor;
use core::fmt;
use core::fmt::Debug;
use std::{marker::PhantomData, str::FromStr};
use crate::{
de::{Error, Visitor, XmlCData, XmlText},
Deserialize, Deserializer, Serialize, Serializer,
};
pub struct FromTrimmedTextVisitor<T> {
_marker: PhantomData<fn() -> T>,
}
impl<T> Default for FromTrimmedTextVisitor<T> {
fn default() -> Self {
Self {
_marker: PhantomData,
}
}
}
impl<'de, T> Visitor<'de> for FromTrimmedTextVisitor<T>
where
T: FromStr,
{
type Value = Trim<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a string")
}
fn visit_text<E, V>(self, v: V) -> Result<Self::Value, E>
where
E: Error,
V: XmlText<'de>,
{
v.into_string()
.trim()
.parse()
.map(Trim)
.map_err(|_| E::custom("invalid value"))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Trim<T>(pub T);
impl<'de, T: FromStr> Deserialize<'de> for Trim<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_any(FromTrimmedTextVisitor::default())
}
}
impl<T: AsRef<str>> Serialize for Trim<T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.as_ref().serialize(serializer)
}
}
pub struct FromTextVisitor<T: FromStr> {
_marker: PhantomData<fn() -> T>,
}
impl<T: FromStr> Default for FromTextVisitor<T> {
fn default() -> Self {
Self {
_marker: PhantomData,
}
}
}
impl<'de, T: Deserialize<'de>> Visitor<'de> for FromTextVisitor<T>
where
T: FromStr,
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a string")
}
fn visit_text<E, V>(self, v: V) -> Result<Self::Value, E>
where
E: Error,
V: XmlText<'de>,
{
v.into_string()
.parse()
.map_err(|_| E::custom("invalid value"))
}
}
pub struct FromStrVisitor<T> {
_marker: PhantomData<fn() -> T>,
}
impl<T> Default for FromStrVisitor<T> {
fn default() -> Self {
Self {
_marker: PhantomData,
}
}
}
impl<'de, T: Deserialize<'de>> Visitor<'de> for FromStrVisitor<T>
where
T: FromStr,
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a string")
}
fn visit_text<E, V>(self, v: V) -> Result<Self::Value, E>
where
E: Error,
V: XmlText<'de>,
{
FromTextVisitor::default().visit_text(v)
}
fn visit_cdata<E, V>(self, v: V) -> Result<Self::Value, E>
where
E: Error,
V: XmlCData<'de>,
{
FromCDataVisitor::default().visit_cdata(v)
}
}
impl<'de> Deserialize<'de> for String {
fn deserialize<D: Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
reader.deserialize_any(FromStrVisitor::default())
}
}
impl Serialize for String {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_str().serialize(serializer)
}
}
impl Serialize for &str {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_text(self)
}
}
impl Serialize for str {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_text(self)
}
}