#![cfg(feature = "serde_compat")]
use crate::{PetitMap, PetitSet};
use core::marker::PhantomData;
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeSeq,
Deserialize, Serialize,
};
use std::fmt;
mod petitmap {
use super::*;
impl<K: Serialize, V: Serialize, const CAP: usize> Serialize for PetitMap<K, V, CAP> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(Some(CAP))?;
for i in 0..CAP {
seq.serialize_element(&self.storage[i])?;
}
seq.end()
}
}
impl<'de, K: Deserialize<'de> + Eq, V: Deserialize<'de>, const CAP: usize> Deserialize<'de>
for PetitMap<K, V, CAP>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(PetitMapVisitor::new())
}
}
#[derive(Debug)]
struct PetitMapVisitor<K, V, const CAP: usize> {
marker: PhantomData<fn() -> PetitMap<K, V, CAP>>,
}
impl<K, V, const CAP: usize> PetitMapVisitor<K, V, CAP> {
fn new() -> Self {
PetitMapVisitor {
marker: PhantomData,
}
}
}
impl<'de, K, V, const CAP: usize> Visitor<'de> for PetitMapVisitor<K, V, CAP>
where
K: Deserialize<'de> + Eq,
V: Deserialize<'de>,
{
type Value = PetitMap<K, V, CAP>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an array of `Option<T>` values to create a PetitMap.")
}
fn visit_seq<S>(self, mut access: S) -> Result<Self::Value, S::Error>
where
S: SeqAccess<'de>,
{
let mut map: PetitMap<K, V, CAP> = PetitMap::default();
for i in 0..CAP {
let next_element: Option<Option<(K, V)>> = access.next_element()?;
if let Some(element) = next_element {
map.storage[i] = element;
} else {
break;
}
}
Ok(map)
}
}
}
mod petitset {
use super::*;
impl<T: Serialize + Clone, const CAP: usize> Serialize for PetitSet<T, CAP> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut seq = serializer.serialize_seq(Some(CAP))?;
for i in 0..CAP {
let element: Option<&T> = match &self.map.storage[i] {
Some((k, _v)) => Some(k),
None => None,
};
seq.serialize_element(&element)?;
}
seq.end()
}
}
impl<'de, T: Deserialize<'de> + Eq + Clone, const CAP: usize> Deserialize<'de>
for PetitSet<T, CAP>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(PetitSetVisitor::new())
}
}
#[derive(Debug)]
struct PetitSetVisitor<T, const CAP: usize> {
marker: PhantomData<fn() -> PetitSet<T, CAP>>,
}
impl<T, const CAP: usize> PetitSetVisitor<T, CAP> {
fn new() -> Self {
PetitSetVisitor {
marker: PhantomData,
}
}
}
impl<'de, T, const CAP: usize> Visitor<'de> for PetitSetVisitor<T, CAP>
where
T: Deserialize<'de> + Eq + Clone,
{
type Value = PetitSet<T, CAP>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an array of `Option<T>` values to create a PetitSet.")
}
fn visit_seq<S>(self, mut access: S) -> Result<Self::Value, S::Error>
where
S: SeqAccess<'de>,
{
let mut set: PetitSet<T, CAP> = PetitSet::default();
for i in 0..CAP {
let next_element: Option<Option<T>> = access.next_element()?;
if let Some(element) = next_element {
set.map.storage[i] = match element {
Some(e) => Some((e, ())),
None => None,
};
} else {
break;
}
}
Ok(set)
}
}
}