diff --git a/Cargo.toml b/Cargo.toml index dc3ec25..9d6b37f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ authors = ["logaritmisk "] [dependencies] unreachable = "1.0" +serde = "1.0" [profile.release] lto = true diff --git a/src/lib.rs b/src/lib.rs index 1502bad..8585768 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,15 @@ extern crate unreachable; +extern crate serde; +use std::fmt; use std::ops; use std::iter::{FromIterator, IntoIterator, Iterator}; use std::default::Default; use std::collections::HashMap; +use serde::ser::{self, Serialize}; +use serde::de::{self, Deserialize, Visitor, SeqAccess}; + mod hasher; use hasher::BitBuildHasher; @@ -59,6 +64,11 @@ impl BitSet { self.nbits == 0 } + pub fn clear(&mut self) { + self.blocks.clear(); + self.nbits = 0; + } + #[inline] pub fn insert(&mut self, value: u64) -> bool { let (block, bit) = block_bit(value, BITS); @@ -310,6 +320,83 @@ impl<'a> ops::BitOr<&'a Self> for BitSet { } } +impl Serialize for BitSet { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + serializer.collect_seq(self) + } +} + +impl<'de> Deserialize<'de> for BitSet { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct SeqVisitor; + + impl<'de> Visitor<'de> for SeqVisitor { + type Value = BitSet; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut values = BitSet::new(); + + while let Some(value) = try!(seq.next_element()) { + BitSet::insert(&mut values, value); + } + + Ok(values) + } + } + + let visitor = SeqVisitor; + + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: de::Deserializer<'de>, + { + struct SeqInPlaceVisitor<'a>(&'a mut BitSet); + + impl<'a, 'de> Visitor<'de> for SeqInPlaceVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq(mut self, mut seq: A) -> Result<(), A::Error> + where + A: SeqAccess<'de>, + { + BitSet::clear(&mut self.0); + + while let Some(value) = try!(seq.next_element()) { + BitSet::insert(&mut self.0, value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(SeqInPlaceVisitor(place)) + } +} + + #[cfg(test)] mod tests { use super::*;