use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, SeqAccess};
use serde::ser::{Serialize, Serializer};
use std::fmt::{self, Display};
use std::marker::PhantomData;
use std::str::FromStr;
pub fn deserialize_string_or_struct<'de, T, D>(d: D) -> Result<T, D::Error>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
D: Deserializer<'de>,
{
struct StringOrStruct<T>(PhantomData<T>);
impl<'de, T> de::Visitor<'de> for StringOrStruct<T>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
{
type Value = T;
fn visit_str<E>(self, value: &str) -> Result<T, E>
where
E: de::Error,
{
FromStr::from_str(value).map_err(|err| {
de::Error::custom(format!("{err}"))
})
}
fn visit_map<M>(self, visitor: M) -> Result<T, M::Error>
where
M: de::MapAccess<'de>,
{
let mvd = de::value::MapAccessDeserializer::new(visitor);
Deserialize::deserialize(mvd)
}
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a string or a map")
}
}
d.deserialize_any(StringOrStruct(PhantomData))
}
pub fn deserialize_opt_string_or_struct<'de, T, D>(d: D) -> Result<Option<T>, D::Error>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
D: Deserializer<'de>,
{
struct OptStringOrStruct<T>(PhantomData<T>);
impl<'de, T> de::Visitor<'de> for OptStringOrStruct<T>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
{
type Value = Option<T>;
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserialize_string_or_struct(deserializer).map(Some)
}
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a null, a string or a map")
}
}
d.deserialize_option(OptStringOrStruct(PhantomData))
}
pub trait SerializeStringOrStruct: Serialize {
fn serialize_string_or_struct<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer;
}
pub fn serialize_string_or_struct<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: SerializeStringOrStruct,
S: Serializer,
{
value.serialize_string_or_struct(serializer)
}
pub fn serialize_opt_string_or_struct<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
where
T: SerializeStringOrStruct,
S: Serializer,
{
struct Wrap<'a, T>(&'a T)
where
T: SerializeStringOrStruct;
impl<'a, T> Serialize for Wrap<'a, T>
where
T: 'a + SerializeStringOrStruct,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Wrap(v) => serialize_string_or_struct(v, serializer),
}
}
}
match *value {
None => serializer.serialize_none(),
Some(ref v) => serializer.serialize_some(&Wrap(v)),
}
}
pub fn deserialize_opt_box_string_or_struct<'de, T, D>(d: D) -> Result<Option<Box<T>>, D::Error>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
D: Deserializer<'de>,
{
struct OptBoxStringOrStruct<T>(PhantomData<T>);
impl<'de, T> de::Visitor<'de> for OptBoxStringOrStruct<T>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
{
type Value = Option<Box<T>>;
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserialize_string_or_struct(deserializer).map(|e| Some(Box::new(e)))
}
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a null, a string or a map")
}
}
d.deserialize_option(OptBoxStringOrStruct(PhantomData))
}
pub fn serialize_opt_box_string_or_struct<T, S>(value: &Option<Box<T>>, serializer: S) -> Result<S::Ok, S::Error>
where
T: SerializeStringOrStruct,
S: Serializer,
{
struct Wrap<'a, T>(&'a T)
where
T: SerializeStringOrStruct;
impl<'a, T> Serialize for Wrap<'a, T>
where
T: 'a + SerializeStringOrStruct,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Wrap(v) => serialize_string_or_struct(v, serializer),
}
}
}
match *value {
None => serializer.serialize_none(),
Some(ref v) => serializer.serialize_some(&Wrap(v.as_ref())),
}
}
#[derive(Debug, Clone)]
pub struct SeqAccessError;
#[allow(dead_code)]
pub fn deserialize_vec_box_string_or_struct<'de, T, D>(d: D) -> Result<Vec<Box<T>>, D::Error>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
D: Deserializer<'de>,
{
struct VecBoxStringOrStruct<T>(PhantomData<T>);
struct SeqAccessStringOrStruct<T>(PhantomData<T>);
impl<'de, T> de::SeqAccess<'de> for SeqAccessStringOrStruct<T>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
{
type Error = serde_json::Error;
fn next_element_seed<A>(
&mut self,
_v: A,
) -> Result<Option<<A as DeserializeSeed<'de>>::Value>, <Self as SeqAccess<'de>>::Error>
where
A: DeserializeSeed<'de>,
{
todo!()
}
}
impl<'de, T> de::Visitor<'de> for VecBoxStringOrStruct<T>
where
T: Deserialize<'de> + FromStr,
<T as FromStr>::Err: Display,
{
type Value = Vec<Box<T>>;
fn visit_seq<A>(self, mut visitor: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = Vec::new();
while let Some(value) = visitor.next_element()? {
values.push(value);
}
Ok(values)
}
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "an array of values")
}
}
d.deserialize_seq(VecBoxStringOrStruct(PhantomData))
}
#[allow(dead_code)]
pub fn serialize_vec_box_string_or_struct<T, S>(_value: &[Box<T>], serializer: S) -> Result<S::Ok, S::Error>
where
T: SerializeStringOrStruct,
S: Serializer,
{
struct Wrap<'a, T>(&'a T)
where
T: SerializeStringOrStruct;
impl<'a, T> Serialize for Wrap<'a, T>
where
T: 'a + SerializeStringOrStruct,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Wrap(v) => serialize_string_or_struct(v, serializer),
}
}
}
serializer.serialize_none()
}