diff --git a/Cargo.toml b/Cargo.toml index f7ba954..4557146 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,9 @@ edition = "2021" [dependencies] num-traits = "0.2" +serde = { version = "1.0.188", optional = true} [dev-dependencies] maplit = "1.0" rand = "0.8.5" - +serde_json = "1.0.107" diff --git a/README.md b/README.md index 11b4138..6402b1c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ union, etc. are of course still supported. [multiset]: https://en.wikipedia.org/wiki/Set_(abstract_data_type)#Multiset +## Cargo Features + +- `serde` implements `serde::Serialize` and `serde::Deserialize` for `Counter`. + ## Examples ### Just count an iterable diff --git a/src/impls.rs b/src/impls.rs index afde736..c83fc0a 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -7,6 +7,8 @@ mod from_iterator; mod index; mod intersection; mod into_iterator; +#[cfg(feature = "serde")] +mod serialize; mod sub_iterable; mod sub_self; mod union; diff --git a/src/impls/serialize.rs b/src/impls/serialize.rs new file mode 100644 index 0000000..ad6301b --- /dev/null +++ b/src/impls/serialize.rs @@ -0,0 +1,32 @@ +use crate::Counter; + +use std::hash::Hash; +use num_traits::Zero; +use serde::{Serialize, Deserialize}; +use serde::ser::Serializer; +use serde::de::Deserializer; + + +impl Serialize for Counter +where + T: Serialize + Hash + Eq, + N: Serialize, +{ + fn serialize(&self, serializer:S) -> Result + where S: Serializer { + self.map.serialize(serializer) + } +} + +impl<'de, T, N> Deserialize<'de> for Counter +where + T: Deserialize<'de> + Hash + Eq, + N: Deserialize<'de> + Zero, +{ + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> { + let map = <_>::deserialize(deserializer)?; + let zero = N::zero(); + Ok(Counter { map, zero }) + } +} \ No newline at end of file diff --git a/tests/tests.rs b/tests/tests.rs index 72e24d6..24dc665 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -185,4 +185,13 @@ mod tests { a[&'e'] = -2; assert!(a.is_subset(&b)); } + + #[cfg(feature = "serde")] + #[test] + fn test_serialize_deserialize() { + let a = "abbccc".chars().collect::>(); + let serialized = serde_json::to_string(&a).unwrap(); + let b: Counter = serde_json::from_str(&serialized).unwrap(); + assert!(a == b) + } }