use std::fmt;
use std::marker::PhantomData;
use serde::de::{self, SeqAccess, Visitor};
use serde::Deserialize;
#[derive(Default)]
pub struct GoVecVisitor<T, D = T> {
return_type: PhantomData<T>,
deserialize_type: PhantomData<D>,
}
impl<T, D> GoVecVisitor<T, D> {
pub fn new() -> Self {
Self {
return_type: PhantomData,
deserialize_type: PhantomData,
}
}
}
impl<'de, T, D> Visitor<'de> for GoVecVisitor<T, D>
where
T: From<D>,
D: Deserialize<'de>,
{
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a vector of serializable objects or null")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
where
A: SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Some(elem) = seq.next_element::<D>()? {
vec.push(T::from(elem));
}
Ok(vec)
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Vec::new())
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_none()
}
}
pub mod go_vec_visitor {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, SerializeSeq, Serializer};
use super::*;
pub fn serialize<S, T>(m: &[T], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize,
{
let mut seq = serializer.serialize_seq(Some(m.len()))?;
for e in m {
seq.serialize_element(&e)?;
}
seq.end()
}
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
deserializer.deserialize_any(GoVecVisitor::<T>::new())
}
}
#[cfg(test)]
mod tests {
use serde::{Deserialize, Deserializer};
use serde_json::from_str;
use super::{go_vec_visitor, *};
#[test]
fn test_json_basic() {
struct BasicJson(Vec<u8>);
impl<'de> Deserialize<'de> for BasicJson {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self(
deserializer.deserialize_any(GoVecVisitor::<u8>::new())?,
))
}
}
let null_json = r#"null"#;
let BasicJson(deserialized) = from_str(null_json).unwrap();
assert_eq!(deserialized, [0u8; 0]);
let empty_array = r#"[]"#;
let BasicJson(deserialized) = from_str(empty_array).unwrap();
assert_eq!(deserialized, [0u8; 0]);
let with_values = r#"[1, 2]"#;
let BasicJson(deserialized) = from_str(with_values).unwrap();
assert_eq!(deserialized, [1, 2]);
}
#[test]
fn serialize_through_other() {
#[derive(Debug, PartialEq, Default)]
struct TestOther(String);
impl From<u8> for TestOther {
fn from(i: u8) -> Self {
Self(i.to_string())
}
}
struct BasicJson(Vec<TestOther>);
impl<'de> Deserialize<'de> for BasicJson {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self(deserializer.deserialize_any(GoVecVisitor::<
TestOther,
u8,
>::new(
))?))
}
}
let null_json = r#"null"#;
let BasicJson(deserialized) = from_str(null_json).unwrap();
assert_eq!(deserialized, []);
let empty_array = r#"[]"#;
let BasicJson(deserialized) = from_str(empty_array).unwrap();
assert_eq!(deserialized, []);
let with_values = r#"[1, 2]"#;
let BasicJson(deserialized) = from_str(with_values).unwrap();
assert_eq!(
deserialized,
[TestOther("1".to_owned()), TestOther("2".to_owned())]
);
}
#[test]
fn standard_vec() {
#[derive(Deserialize)]
#[serde(transparent)]
struct BasicJson {
#[serde(with = "go_vec_visitor")]
ints: Vec<u8>,
}
let null_json = r#"null"#;
let BasicJson { ints } = from_str(null_json).unwrap();
assert_eq!(ints, [0u8; 0]);
let empty_array = r#"[]"#;
let BasicJson { ints } = from_str(empty_array).unwrap();
assert_eq!(ints, [0u8; 0]);
let with_values = r#"[1, 2]"#;
let BasicJson { ints } = from_str(with_values).unwrap();
assert_eq!(ints, [1, 2]);
}
}