use serde::ser::{Impossible, SerializeStructVariant, SerializeTupleVariant};
use serde::{de, ser};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::marker::PhantomData;
pub fn deserialize_untagged_enum_case_insensitive<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: Deserialize<'de>,
D: Deserializer<'de>,
{
use serde::de::Error;
use serde_json::Value;
T::deserialize(Value::String(
String::deserialize(deserializer)?.to_lowercase(),
))
.map_err(Error::custom)
}
pub fn deserialize_space_delimited_vec<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: Default + Deserialize<'de>,
D: Deserializer<'de>,
{
use serde::de::Error;
use serde_json::Value;
if let Some(space_delimited) = Option::<String>::deserialize(deserializer)? {
let entries = space_delimited
.split(' ')
.map(|s| Value::String(s.to_string()))
.collect();
T::deserialize(Value::Array(entries)).map_err(Error::custom)
} else {
Ok(T::default())
}
}
pub fn deserialize_optional_string_or_vec_string<'de, D>(
deserializer: D,
) -> Result<Option<Vec<String>>, D::Error>
where
D: Deserializer<'de>,
{
struct StringOrVec(PhantomData<Vec<String>>);
impl<'de> de::Visitor<'de> for StringOrVec {
type Value = Option<Vec<String>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string or list of strings")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Some(vec![value.to_owned()]))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
where
S: de::SeqAccess<'de>,
{
Deserialize::deserialize(de::value::SeqAccessDeserializer::new(visitor)).map(Some)
}
}
deserializer.deserialize_any(StringOrVec(PhantomData))
}
pub fn serialize_space_delimited_vec<T, S>(
vec_opt: &Option<Vec<T>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
T: AsRef<str>,
S: Serializer,
{
if let Some(ref vec) = *vec_opt {
let space_delimited = vec.iter().map(|s| s.as_ref()).collect::<Vec<_>>().join(" ");
serializer.serialize_str(&space_delimited)
} else {
serializer.serialize_none()
}
}
pub fn variant_name<T: Serialize>(t: &T) -> &'static str {
#[derive(Debug)]
struct NotEnum;
type Result<T> = std::result::Result<T, NotEnum>;
impl std::error::Error for NotEnum {
fn description(&self) -> &str {
"not struct"
}
}
impl std::fmt::Display for NotEnum {
fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
unimplemented!()
}
}
impl ser::Error for NotEnum {
fn custom<T: std::fmt::Display>(_msg: T) -> Self {
NotEnum
}
}
struct VariantName;
impl Serializer for VariantName {
type Ok = &'static str;
type Error = NotEnum;
type SerializeSeq = Impossible<Self::Ok, Self::Error>;
type SerializeTuple = Impossible<Self::Ok, Self::Error>;
type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
type SerializeTupleVariant = Enum;
type SerializeMap = Impossible<Self::Ok, Self::Error>;
type SerializeStruct = Impossible<Self::Ok, Self::Error>;
type SerializeStructVariant = Enum;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_char(self, _v: char) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_str(self, _v: &str) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_none(self) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_unit(self) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok> {
Ok(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_name: &'static str,
_value: &T,
) -> Result<Self::Ok> {
Err(NotEnum)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
_value: &T,
) -> Result<Self::Ok> {
Ok(variant)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(NotEnum)
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Err(NotEnum)
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(NotEnum)
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
Ok(Enum(variant))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Err(NotEnum)
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct> {
Err(NotEnum)
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
Ok(Enum(variant))
}
}
struct Enum(&'static str);
impl SerializeStructVariant for Enum {
type Ok = &'static str;
type Error = NotEnum;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
_key: &'static str,
_value: &T,
) -> Result<()> {
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(self.0)
}
}
impl SerializeTupleVariant for Enum {
type Ok = &'static str;
type Error = NotEnum;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<()> {
Ok(())
}
fn end(self) -> Result<Self::Ok> {
Ok(self.0)
}
}
t.serialize(VariantName).unwrap()
}