#[cfg(not(feature = "std"))] use core as std; use crate::{Block, FixedBitSet, BYTES}; use alloc::vec::Vec; use core::{convert::TryFrom, fmt}; use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor}; use serde::ser::{Serialize, SerializeStruct, Serializer}; struct BitSetByteSerializer<'a>(&'a FixedBitSet); impl Serialize for FixedBitSet { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let mut struct_serializer = serializer.serialize_struct("FixedBitset", 2)?; struct_serializer.serialize_field("length", &(self.length as u64))?; struct_serializer.serialize_field("data", &BitSetByteSerializer(self))?; struct_serializer.end() } } impl<'a> Serialize for BitSetByteSerializer<'a> { fn serialize(&self, serializer: S) -> Result where S: Serializer, { let len = self.0.as_slice().len() * BYTES; // PERF: Figure out a way to do this without allocating. let mut temp = Vec::with_capacity(len); for block in self.0.as_slice() { temp.extend(&block.to_le_bytes()); } serializer.serialize_bytes(&temp) } } impl<'de> Deserialize<'de> for FixedBitSet { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { enum Field { Length, Data, } fn bytes_to_data(length: usize, input: &[u8]) -> Vec { let block_len = length / BYTES + 1; let mut data = Vec::with_capacity(block_len); for chunk in input.chunks(BYTES) { match <&[u8; BYTES]>::try_from(chunk) { Ok(bytes) => data.push(usize::from_le_bytes(*bytes)), Err(_) => { let mut bytes = [0u8; BYTES]; bytes[0..BYTES].copy_from_slice(chunk); data.push(usize::from_le_bytes(bytes)); } } } data } impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { struct FieldVisitor; impl<'de> Visitor<'de> for FieldVisitor { type Value = Field; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("`length` or `data`") } fn visit_str(self, value: &str) -> Result where E: de::Error, { match value { "length" => Ok(Field::Length), "data" => Ok(Field::Data), _ => Err(de::Error::unknown_field(value, FIELDS)), } } } deserializer.deserialize_identifier(FieldVisitor) } } struct FixedBitSetVisitor; impl<'de> Visitor<'de> for FixedBitSetVisitor { type Value = FixedBitSet; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct Duration") } fn visit_seq(self, mut seq: V) -> Result where V: SeqAccess<'de>, { let length = seq .next_element()? .ok_or_else(|| de::Error::invalid_length(0, &self))?; let data: &[u8] = seq .next_element()? .ok_or_else(|| de::Error::invalid_length(1, &self))?; let data = bytes_to_data(length, data); Ok(FixedBitSet::with_capacity_and_blocks(length, data)) } fn visit_map(self, mut map: V) -> Result where V: MapAccess<'de>, { let mut length = None; let mut temp: Option<&[u8]> = None; while let Some(key) = map.next_key()? { match key { Field::Length => { if length.is_some() { return Err(de::Error::duplicate_field("length")); } length = Some(map.next_value()?); } Field::Data => { if temp.is_some() { return Err(de::Error::duplicate_field("data")); } temp = Some(map.next_value()?); } } } let length = length.ok_or_else(|| de::Error::missing_field("length"))?; let data = temp.ok_or_else(|| de::Error::missing_field("data"))?; let data = bytes_to_data(length, data); Ok(FixedBitSet::with_capacity_and_blocks(length, data)) } } const FIELDS: &'static [&'static str] = &["length", "data"]; deserializer.deserialize_struct("Duration", FIELDS, FixedBitSetVisitor) } }