Skip to content

Commit

Permalink
✨ Impl Deserialize for MmapVec
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurlm committed Oct 22, 2023
1 parent a8bacff commit d419131
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,20 @@ use std::{
path::PathBuf,
};

#[cfg(feature = "serde")]
use std::marker::PhantomData;

pub use segment::Segment;
pub use segment_builder::{DefaultSegmentBuilder, SegmentBuilder};
pub use stats::MmapStats;
pub use vec_builder::MmapVecBuilder;

#[cfg(feature = "serde")]
use serde::{ser::SerializeSeq, Serialize, Serializer};
use serde::{
de::{SeqAccess, Visitor},
ser::SerializeSeq,
Deserialize, Deserializer, Serialize, Serializer,
};

use crate::utils::page_size;

Expand Down Expand Up @@ -492,3 +499,60 @@ where
seq.end()
}
}

#[cfg(feature = "serde")]
struct MmapVecVisitor<T, B: SegmentBuilder> {
_marker: PhantomData<fn() -> MmapVec<T, B>>,
}

#[cfg(feature = "serde")]
impl<T, B: SegmentBuilder> MmapVecVisitor<T, B> {
fn new() -> Self {
Self {
_marker: PhantomData,
}
}
}

#[cfg(feature = "serde")]
impl<'de, T, B> Visitor<'de> for MmapVecVisitor<T, B>
where
T: Deserialize<'de>,
B: SegmentBuilder,
{
type Value = MmapVec<T, B>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("expected sequence of element")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
use serde::de::Error;

let capacity = seq.size_hint().unwrap_or(0);
let mut output = MmapVec::<T, B>::with_capacity(capacity).map_err(Error::custom)?;

while let Some(element) = seq.next_element()? {
output.push(element).map_err(Error::custom)?;
}

Ok(output)
}
}

#[cfg(feature = "serde")]
impl<'de, T, B> Deserialize<'de> for MmapVec<T, B>
where
T: Deserialize<'de>,
B: SegmentBuilder,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(MmapVecVisitor::new())
}
}
13 changes: 13 additions & 0 deletions tests/test_vec_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,16 @@ fn test_serializer() {
assert_eq!(serde_json::to_string(&vec).unwrap(), "[42,8,52]");
}
}

#[test]
#[cfg(feature = "serde")]
fn test_deserialize() {
{
let vec: MmapVec<u32> = serde_json::from_str("[]").unwrap();
assert_eq!(&vec[..], Vec::<u32>::new());
}
{
let vec: MmapVec<u32> = serde_json::from_str("[8,6,42]").unwrap();
assert_eq!(&vec[..], [8, 6, 42]);
}
}

0 comments on commit d419131

Please sign in to comment.