//! Serde serialization/deserialization implementation use core::fmt; use core::marker::PhantomData; use serde::de::{self, SeqAccess, Visitor}; use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer}; use {ArrayLength, GenericArray}; impl Serialize for GenericArray where T: Serialize, N: ArrayLength, { #[inline] fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut tup = serializer.serialize_tuple(N::USIZE)?; for el in self { tup.serialize_element(el)?; } tup.end() } } struct GAVisitor { _t: PhantomData, _n: PhantomData, } impl<'de, T, N> Visitor<'de> for GAVisitor where T: Deserialize<'de> + Default, N: ArrayLength, { type Value = GenericArray; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct GenericArray") } fn visit_seq(self, mut seq: A) -> Result, A::Error> where A: SeqAccess<'de>, { let mut result = GenericArray::default(); for i in 0..N::USIZE { result[i] = seq .next_element()? .ok_or_else(|| de::Error::invalid_length(i, &self))?; } Ok(result) } } impl<'de, T, N> Deserialize<'de> for GenericArray where T: Deserialize<'de> + Default, N: ArrayLength, { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let visitor = GAVisitor { _t: PhantomData, _n: PhantomData, }; deserializer.deserialize_tuple(N::USIZE, visitor) } } #[cfg(test)] mod tests { use super::*; use bincode; use typenum; #[test] fn test_serialize() { let array = GenericArray::::default(); let serialized = bincode::serialize(&array); assert!(serialized.is_ok()); } #[test] fn test_deserialize() { let mut array = GenericArray::::default(); array[0] = 1; array[1] = 2; let serialized = bincode::serialize(&array).unwrap(); let deserialized = bincode::deserialize::>(&serialized); assert!(deserialized.is_ok()); let array = deserialized.unwrap(); assert_eq!(array[0], 1); assert_eq!(array[1], 2); } #[test] fn test_serialized_size() { let array = GenericArray::::default(); let size = bincode::serialized_size(&array).unwrap(); assert_eq!(size, 1); } }