use circular_buffer::CircularBuffer;
#[derive(Debug, Clone, Default)]
pub struct SerdeCircularBuffer<const N: usize, T>(pub CircularBuffer<N, T>);
impl<const N: usize, T> SerdeCircularBuffer<N, T> {
pub fn push_back(&mut self, item: T) -> Option<T> {
self.0.push_back(item)
}
pub fn nth_back(&self, index: usize) -> Option<&T> {
self.0.nth_back(index)
}
}
#[cfg(feature = "serde")]
mod wrapper {
use super::SerdeCircularBuffer;
use circular_buffer::CircularBuffer;
use core::fmt;
use serde::{
Deserialize, Deserializer, Serialize, Serializer,
de::{SeqAccess, Visitor},
ser::SerializeSeq,
};
impl<const N: usize, T> Serialize for SerdeCircularBuffer<N, T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let iter = self.0.iter();
let mut seq = serializer.serialize_seq(Some(iter.len()))?;
for elem in iter {
seq.serialize_element(elem)?;
}
seq.end()
}
}
impl<'de, const N: usize, T> Deserialize<'de> for SerdeCircularBuffer<N, T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct CircularBufferVisitor<const N: usize, T> {
marker: std::marker::PhantomData<T>,
}
impl<'de, const N: usize, T> Visitor<'de> for CircularBufferVisitor<N, T>
where
T: Deserialize<'de>,
{
type Value = SerdeCircularBuffer<N, T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a sequence of elements up to capacity {}", N)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut buffer = CircularBuffer::<N, T>::new();
while let Some(elem) = seq.next_element()? {
buffer.push_back(elem);
}
Ok(SerdeCircularBuffer(buffer))
}
}
deserializer.deserialize_seq(CircularBufferVisitor {
marker: std::marker::PhantomData,
})
}
}
}