diff --git a/CHANGELOG.md b/CHANGELOG.md index e304be7..19bd011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Renamed `InclusiveInterval::contains()` to `InclusiveInterval::contains_point()` to match the new `InclusiveInterval::contains_interval()` method +- `serde`'s Serialize and Deserialize implementations are now optional via a + "serde" feature which is documented in the features section of the + readme/top-level module docs ## 0.8.0 - 2024-01-28 diff --git a/Cargo.toml b/Cargo.toml index a23dcd8..eef890d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,9 @@ keywords = ["data-structures", "map", "data", "library"] categories = ["data-structures"] [dependencies] -serde = { version = "1.0.193", features = ["derive"], default-features = false } +serde = { version = "1.0.193", features = [ + "derive", +], default-features = false, optional = true } btree_monstrousity = { version = "0.0.4", features = [ "btree_drain_filter", "btree_cursors", @@ -24,6 +26,10 @@ btree_monstrousity = { version = "0.0.4", features = [ itertools = { version = "0.12.0", default-features = false } smallvec = { version = "1.13.1", default-features = false } +[features] +default = [] +serde = ["dep:serde"] + [dev-dependencies] pretty_assertions = "1.4.0" diff --git a/README.md b/README.md index a982f35..b18bd30 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,7 @@ from an empty map if the type was an infinite type such as `BigInt` since it has no maximum value. A handy trick you can use to pretend to have infinite types when you -don't expect to reach to top end of your type is to use [`Actual -Infinity`] to pretend you have an `Infinity`. For example, if you were +don't expect to reach to top end of your type is to use [`Actual Infinity`] to pretend you have an `Infinity`. For example, if you were using `u8` as your point type then you could create a wrapper type such as this: @@ -291,7 +290,10 @@ See Wikipedia's article on mathematical Intervals: ## Features -This crate currently has no features +|Feature Name| Description| +|-----------|-----| +|`default`|The implicit default feature enabled by default which currently does not activate any other features| +|`serde`|Enables the optional `serde` dependency and implements `serde::Serialize` and `serde::Deserialize` on all the types in this crate| ## Credit @@ -354,26 +356,26 @@ topic area, beware my biases when reading: - and Both essentially identical to `store-interval-tree` as it looks like `store-interval-tree` is a fork of `rudac`'s interval tree. `bio` in - particular seems targeted at bioinfographics. + particular seems targeted at bio-infographics. +[`actual infinity`]: https://en.wikipedia.org/wiki/Actual_infinity +[`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html [`btreemap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html [`btree_monstrousity`]: https://github.com/ripytide/btree_monstrousity -[`range`]: https://doc.rust-lang.org/std/ops/struct.Range.html -[`rangemap`]: https://docs.rs/rangemap/latest/rangemap/ -[`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +[`continuous`]: https://en.wikipedia.org/wiki/List_of_continuity-related_mathematical_topics [`copse`]: https://github.com/eggyal/copse +[`discrete_range_map`]: https://docs.rs/discrete_range_map [`discrete`]: https://en.wikipedia.org/wiki/Discrete_mathematics -[`continuous`]: https://en.wikipedia.org/wiki/List_of_continuity-related_mathematical_topics -[`interval-mathematics`]: https://en.wikipedia.org/wiki/Interval_(mathematics) -[`actual infinity`]: https://en.wikipedia.org/wiki/Actual_infinity [`finite`]: https://en.wiktionary.org/wiki/finite#Adjective -[`range_bounds_map`]: https://docs.rs/range_bounds_map -[`discrete_range_map`]: https://docs.rs/discrete_range_map +[`get_key_value_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html#method.get_key_value_at_point +[`gqdit`]: https://docs.rs/nodit/latest/nodit/gqdit/struct.Gqdit.html +[`interval-mathematics`]: https://en.wikipedia.org/wiki/Interval_(mathematics) +[`noditmap`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html +[`noditset`]: https://docs.rs/nodit/latest/nodit/nodit/set/struct.NoditSet.html [`nodit`]: https://docs.rs/nodit -[`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html [`num_bigint`]: https://docs.rs/num-bigint -[`get_key_value_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html#method.get_key_value_at_point -[`NoditMap`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html -[`NoditSet`]: https://docs.rs/nodit/latest/nodit/nodit/set/struct.NoditSet.html -[`ZosditMap`]: https://docs.rs/nodit/latest/nodit/zosdit/map/struct.ZosditMap.html -[`Gqdit`]: https://docs.rs/nodit/latest/nodit/gqdit/struct.Gqdit.html +[`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +[`rangemap`]: https://docs.rs/rangemap/latest/rangemap/ +[`range_bounds_map`]: https://docs.rs/range_bounds_map +[`range`]: https://doc.rust-lang.org/std/ops/struct.Range.html +[`zosditmap`]: https://docs.rs/nodit/latest/nodit/zosdit/map/struct.ZosditMap.html diff --git a/src/gqdit/mod.rs b/src/gqdit/mod.rs index c1fb5b1..17062ca 100644 --- a/src/gqdit/mod.rs +++ b/src/gqdit/mod.rs @@ -6,7 +6,6 @@ use alloc::collections::BTreeSet; use alloc::vec::Vec; use itertools::Itertools; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::interval::{ii, iu, ui, uu}; use crate::utils::invalid_interval_panic; @@ -190,7 +189,8 @@ where //we don't want end ones as they are //handled separately let non_end_gaps = valid_gaps.filter(|gap| { - !gap.contains_point(interval.start()) && !gap.contains_point(interval.end()) + !gap.contains_point(interval.start()) + && !gap.contains_point(interval.end()) }); //instead of using possibly-partial end gaps we will @@ -558,32 +558,41 @@ where } } -impl Serialize for Gqdit -where - I: PointType, - K: IntervalType + Serialize, - D: IdType, - BTreeSet: Serialize, -{ - fn serialize(&self, serializer: S) -> Result +#[cfg(feature = "serde")] +mod serde { + use alloc::collections::BTreeSet; + + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use crate::{Gqdit, IdType, IntervalType, NoditMap, PointType}; + + impl Serialize for Gqdit where - S: Serializer, + I: PointType, + K: IntervalType + Serialize, + D: IdType, + BTreeSet: Serialize, { - self.inner.serialize(serializer) + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.inner.serialize(serializer) + } } -} -impl<'de, I, K, D> Deserialize<'de> for Gqdit -where - I: PointType, - K: IntervalType + Deserialize<'de>, - D: IdType, - BTreeSet: Deserialize<'de>, -{ - fn deserialize(deserializer: De) -> Result + impl<'de, I, K, D> Deserialize<'de> for Gqdit where - De: Deserializer<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, + D: IdType, + BTreeSet: Deserialize<'de>, { - NoditMap::deserialize(deserializer).map(|x| Gqdit { inner: x }) + fn deserialize(deserializer: De) -> Result + where + De: Deserializer<'de>, + { + NoditMap::deserialize(deserializer).map(|x| Gqdit { inner: x }) + } } } diff --git a/src/interval.rs b/src/interval.rs index 9d0fe2e..3157b1e 100644 --- a/src/interval.rs +++ b/src/interval.rs @@ -8,8 +8,6 @@ use core::ops::{Bound, Range, RangeBounds, RangeInclusive}; -use serde::{Deserialize, Serialize}; - use crate::utils::{invalid_interval_panic, sorted_config, SortedConfig}; use crate::{IntervalType, PointType}; @@ -39,7 +37,8 @@ use crate::{IntervalType, PointType}; /// /// let invalid_interval = ee(4, 4); /// ``` -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Interval { /// The start of the interval, inclusive. pub(crate) start: I, @@ -499,7 +498,7 @@ pub trait InclusiveInterval: Copy + From> { fn intersection(&self, other: &Q) -> Option where I: PointType, - Q: IntervalType, + Q: IntervalType, Self: From>, { let intersect_start = I::max(self.start(), other.start()); diff --git a/src/lib.rs b/src/lib.rs index 9f1e16d..86b8468 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,24 +22,23 @@ //! traits on the value type are sometimes `Clone` or `Eq` but only for some //! methods so if in doubt check a methods trait bounds. //! -//! ## `NoditMap` Example using an Inclusive-Inclusive interval +//! ## Example using an Inclusive-Exclusive interval //! //! ```rust -//! use nodit::interval::ii; +//! use nodit::interval::ie; //! use nodit::NoditMap; //! //! let mut map = NoditMap::new(); //! -//! map.insert_strict(ii(0, 4), true); -//! map.insert_strict(ii(5, 10), false); +//! map.insert_strict(ie(0, 5), true); +//! map.insert_strict(ie(5, 10), false); //! -//! assert_eq!(map.overlaps(ii(-2, 12)), true); +//! assert_eq!(map.overlaps(ie(-2, 12)), true); //! assert_eq!(map.contains_point(20), false); //! assert_eq!(map.contains_point(5), true); -//! assert_eq!(map.get_key_value_at_point(2), Ok((&ii(0, 4), &true))); //! ``` //! -//! ## `NoditMap` Example using a custom interval type +//! ## Example using a custom interval type //! //! ```rust //! use std::ops::{Bound, RangeBounds}; @@ -139,8 +138,7 @@ //! since it has no maximum value. //! //! A handy trick you can use to pretend to have infinite types when you -//! don't expect to reach to top end of your type is to use [`Actual -//! Infinity`] to pretend you have an `Infinity`. For example, if you were +//! don't expect to reach to top end of your type is to use [`Actual Infinity`] to pretend you have an `Infinity`. For example, if you were //! using `u8` as your point type then you could create a wrapper type such //! as this: //! @@ -281,7 +279,10 @@ //! //! ## Features //! -//! This crate currently has no features +//! |Feature Name| Description| +//! |-----------|-----| +//! |`default`|The implicit default feature enabled by default which currently does not activate any other features| +//! |`serde`|Enables the optional `serde` dependency and implements `serde::Serialize` and `serde::Deserialize` on all the types in this crate| //! //! ## Credit //! @@ -344,29 +345,29 @@ //! - and //! Both essentially identical to `store-interval-tree` as it looks like //! `store-interval-tree` is a fork of `rudac`'s interval tree. `bio` in -//! particular seems targeted at bioinfographics. +//! particular seems targeted at bio-infographics. //! +//! [`actual infinity`]: https://en.wikipedia.org/wiki/Actual_infinity +//! [`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html //! [`btreemap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html //! [`btree_monstrousity`]: https://github.com/ripytide/btree_monstrousity -//! [`range`]: https://doc.rust-lang.org/std/ops/struct.Range.html -//! [`rangemap`]: https://docs.rs/rangemap/latest/rangemap/ -//! [`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +//! [`continuous`]: https://en.wikipedia.org/wiki/List_of_continuity-related_mathematical_topics //! [`copse`]: https://github.com/eggyal/copse +//! [`discrete_range_map`]: https://docs.rs/discrete_range_map //! [`discrete`]: https://en.wikipedia.org/wiki/Discrete_mathematics -//! [`continuous`]: https://en.wikipedia.org/wiki/List_of_continuity-related_mathematical_topics -//! [`interval-mathematics`]: https://en.wikipedia.org/wiki/Interval_(mathematics) -//! [`actual infinity`]: https://en.wikipedia.org/wiki/Actual_infinity //! [`finite`]: https://en.wiktionary.org/wiki/finite#Adjective -//! [`range_bounds_map`]: https://docs.rs/range_bounds_map -//! [`discrete_range_map`]: https://docs.rs/discrete_range_map +//! [`get_key_value_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html#method.get_key_value_at_point +//! [`gqdit`]: https://docs.rs/nodit/latest/nodit/gqdit/struct.Gqdit.html +//! [`interval-mathematics`]: https://en.wikipedia.org/wiki/Interval_(mathematics) +//! [`noditmap`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html +//! [`noditset`]: https://docs.rs/nodit/latest/nodit/nodit/set/struct.NoditSet.html //! [`nodit`]: https://docs.rs/nodit -//! [`bigint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html //! [`num_bigint`]: https://docs.rs/num-bigint -//! [`get_key_value_at_point()`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html#method.get_key_value_at_point -//! [`NoditMap`]: https://docs.rs/nodit/latest/nodit/nodit/map/struct.NoditMap.html -//! [`NoditSet`]: https://docs.rs/nodit/latest/nodit/nodit/set/struct.NoditSet.html -//! [`ZosditMap`]: https://docs.rs/nodit/latest/nodit/zosdit/map/struct.ZosditMap.html -//! [`Gqdit`]: https://docs.rs/nodit/latest/nodit/gqdit/struct.Gqdit.html +//! [`rangeinclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html +//! [`rangemap`]: https://docs.rs/rangemap/latest/rangemap/ +//! [`range_bounds_map`]: https://docs.rs/range_bounds_map +//! [`range`]: https://doc.rust-lang.org/std/ops/struct.Range.html +//! [`zosditmap`]: https://docs.rs/nodit/latest/nodit/zosdit/map/struct.ZosditMap.html #![allow(clippy::tabs_in_doc_comments)] #![allow(clippy::needless_return)] diff --git a/src/nodit/map.rs b/src/nodit/map.rs index 1e65a5e..53ec0ca 100644 --- a/src/nodit/map.rs +++ b/src/nodit/map.rs @@ -1,6 +1,5 @@ //! A module containing [`NoditMap`]. -use alloc::fmt; use alloc::vec::Vec; use core::marker::PhantomData; @@ -9,9 +8,6 @@ use btree_monstrousity::btree_map::{ }; use btree_monstrousity::BTreeMap; use itertools::Itertools; -use serde::de::{SeqAccess, Visitor}; -use serde::ser::SerializeSeq; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::utils::{ cut_interval, invalid_interval_panic, overlapping_comp, starts_comp, @@ -1261,7 +1257,7 @@ impl NoditMap { /// let map: NoditMap, bool> = NoditMap::new(); /// ``` pub fn new() -> Self { - Self::default() + Self::default() } /// Returns the number of intervals in the map. @@ -1437,69 +1433,83 @@ impl Default for NoditMap { } } -impl Serialize for NoditMap -where - K: Serialize, - V: Serialize, -{ - fn serialize(&self, serializer: S) -> Result +#[cfg(feature = "serde")] +mod serde { + use core::marker::PhantomData; + + use serde::de::{SeqAccess, Visitor}; + use serde::ser::SerializeSeq; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use crate::{IntervalType, NoditMap, PointType}; + + impl Serialize for NoditMap where - S: Serializer, + K: Serialize, + V: Serialize, { - let mut seq = serializer.serialize_seq(Some(self.len()))?; - for (interval, value) in self.iter() { - seq.serialize_element(&(interval, value))?; + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for (interval, value) in self.iter() { + seq.serialize_element(&(interval, value))?; + } + seq.end() } - seq.end() } -} -impl<'de, I, K, V> Deserialize<'de> for NoditMap -where - I: PointType, - K: IntervalType + Deserialize<'de>, - V: Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result + impl<'de, I, K, V> Deserialize<'de> for NoditMap where - D: Deserializer<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, + V: Deserialize<'de>, { - deserializer.deserialize_seq(NoditMapVisitor { - i: PhantomData, - k: PhantomData, - v: PhantomData, - }) + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(NoditMapVisitor { + i: PhantomData, + k: PhantomData, + v: PhantomData, + }) + } } -} - -struct NoditMapVisitor { - i: PhantomData, - k: PhantomData, - v: PhantomData, -} - -impl<'de, I, K, V> Visitor<'de> for NoditMapVisitor -where - I: PointType, - K: IntervalType + Deserialize<'de>, - V: Deserialize<'de>, -{ - type Value = NoditMap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a NoditMap") + struct NoditMapVisitor { + i: PhantomData, + k: PhantomData, + v: PhantomData, } - fn visit_seq(self, mut access: A) -> Result + impl<'de, I, K, V> Visitor<'de> for NoditMapVisitor where - A: SeqAccess<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, + V: Deserialize<'de>, { - let mut map = NoditMap::new(); - while let Some((interval, value)) = access.next_element()? { - map.insert_strict(interval, value) - .or(Err(serde::de::Error::custom("intervals overlap")))?; + type Value = NoditMap; + + fn expecting( + &self, + formatter: &mut alloc::fmt::Formatter, + ) -> alloc::fmt::Result { + formatter.write_str("a NoditMap") + } + + fn visit_seq(self, mut access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut map = NoditMap::new(); + while let Some((interval, value)) = access.next_element()? { + map.insert_strict(interval, value) + .or(Err(serde::de::Error::custom("intervals overlap")))?; + } + Ok(map) } - Ok(map) } } diff --git a/src/nodit/set.rs b/src/nodit/set.rs index ea4cba4..c1977ef 100644 --- a/src/nodit/set.rs +++ b/src/nodit/set.rs @@ -5,13 +5,6 @@ //! equivalent method's docs on [`NoditMap`] to prevent //! inconsistency. -use core::fmt; -use core::marker::PhantomData; - -use serde::de::{SeqAccess, Visitor}; -use serde::ser::SerializeSeq; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use crate::nodit::map::IntoIter as NoditMapIntoIter; use crate::{IntervalType, NoditMap, OverlapError, PointType}; @@ -229,63 +222,78 @@ where } } -impl Serialize for NoditSet -where - K: Serialize, -{ - fn serialize(&self, serializer: S) -> Result +#[cfg(feature = "serde")] +mod serde { + use core::marker::PhantomData; + + use serde::de::{SeqAccess, Visitor}; + use serde::ser::SerializeSeq; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use crate::{IntervalType, NoditSet, PointType}; + + impl Serialize for NoditSet where - S: Serializer, + K: Serialize, { - let mut seq = serializer.serialize_seq(Some(self.len()))?; - for interval in self.iter() { - seq.serialize_element(&interval)?; + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for interval in self.iter() { + seq.serialize_element(&interval)?; + } + seq.end() } - seq.end() } -} -impl<'de, I, K> Deserialize<'de> for NoditSet -where - I: PointType, - K: IntervalType + Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result + impl<'de, I, K> Deserialize<'de> for NoditSet where - D: Deserializer<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, { - deserializer.deserialize_seq(NoditSetVisitor { - i: PhantomData, - k: PhantomData, - }) + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(NoditSetVisitor { + i: PhantomData, + k: PhantomData, + }) + } } -} - -struct NoditSetVisitor { - i: PhantomData, - k: PhantomData, -} -impl<'de, I, K> Visitor<'de> for NoditSetVisitor -where - I: PointType, - K: IntervalType + Deserialize<'de>, -{ - type Value = NoditSet; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a NoditSet") + struct NoditSetVisitor { + i: PhantomData, + k: PhantomData, } - fn visit_seq(self, mut access: A) -> Result + impl<'de, I, K> Visitor<'de> for NoditSetVisitor where - A: SeqAccess<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, { - let mut set = NoditSet::new(); - while let Some(interval) = access.next_element()? { - set.insert_strict(interval) - .map_err(|_| serde::de::Error::custom("intervals overlap"))?; + type Value = NoditSet; + + fn expecting( + &self, + formatter: &mut alloc::fmt::Formatter, + ) -> alloc::fmt::Result { + formatter.write_str("a NoditSet") + } + + fn visit_seq(self, mut access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut set = NoditSet::new(); + while let Some(interval) = access.next_element()? { + set.insert_strict(interval).map_err(|_| { + serde::de::Error::custom("intervals overlap") + })?; + } + Ok(set) } - Ok(set) } } diff --git a/src/zosdit/map.rs b/src/zosdit/map.rs index 4d06c9a..3c90bc0 100644 --- a/src/zosdit/map.rs +++ b/src/zosdit/map.rs @@ -7,22 +7,18 @@ use alloc::boxed::Box; use alloc::vec::Vec; use core::cmp::Ordering; -use core::fmt; use core::marker::PhantomData; -#[cfg(doc)] -use crate::NoditMap; use btree_monstrousity::btree_map::SearchBoundCustom; use btree_monstrousity::BTreeMap; -use serde::de::{SeqAccess, Visitor}; -use serde::ser::SerializeSeq; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use smallvec::SmallVec; use crate::utils::{ cut_interval, exclusive_comp_generator, inclusive_comp_generator, invalid_interval_panic, }; +#[cfg(doc)] +use crate::NoditMap; use crate::{IntervalType, PointType}; type ValueStore = SmallVec<[V; 2]>; @@ -585,71 +581,85 @@ where } } -impl Serialize for ZosditMap -where - I: PointType, - K: IntervalType + Serialize, - V: Serialize, -{ - fn serialize(&self, serializer: S) -> Result +#[cfg(feature = "serde")] +mod serde { + use core::marker::PhantomData; + + use serde::de::{SeqAccess, Visitor}; + use serde::ser::SerializeSeq; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use crate::{IntervalType, PointType, ZosditMap}; + + impl Serialize for ZosditMap where - S: Serializer, + I: PointType, + K: IntervalType + Serialize, + V: Serialize, { - let mut seq = serializer.serialize_seq(Some(self.len()))?; - for (interval, value) in self.iter() { - seq.serialize_element(&(interval, value))?; + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for (interval, value) in self.iter() { + seq.serialize_element(&(interval, value))?; + } + seq.end() } - seq.end() } -} -impl<'de, I, K, V> Deserialize<'de> for ZosditMap -where - I: PointType, - K: IntervalType + Deserialize<'de>, - V: Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result + impl<'de, I, K, V> Deserialize<'de> for ZosditMap where - D: Deserializer<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, + V: Deserialize<'de>, { - deserializer.deserialize_seq(ZosditMapVisitor { - i: PhantomData, - k: PhantomData, - v: PhantomData, - }) + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(ZosditMapVisitor { + i: PhantomData, + k: PhantomData, + v: PhantomData, + }) + } } -} - -struct ZosditMapVisitor { - i: PhantomData, - k: PhantomData, - v: PhantomData, -} - -impl<'de, I, K, V> Visitor<'de> for ZosditMapVisitor -where - I: PointType, - K: IntervalType + Deserialize<'de>, - V: Deserialize<'de>, -{ - type Value = ZosditMap; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a ZosditMap") + struct ZosditMapVisitor { + i: PhantomData, + k: PhantomData, + v: PhantomData, } - fn visit_seq(self, mut access: A) -> Result + impl<'de, I, K, V> Visitor<'de> for ZosditMapVisitor where - A: SeqAccess<'de>, + I: PointType, + K: IntervalType + Deserialize<'de>, + V: Deserialize<'de>, { - let mut map = ZosditMap::new(); - while let Some((interval, value)) = access.next_element()? { - map.insert_strict_back(interval, value).or(Err( - serde::de::Error::custom("intervals non-zero-overlap"), - ))?; + type Value = ZosditMap; + + fn expecting( + &self, + formatter: &mut alloc::fmt::Formatter, + ) -> alloc::fmt::Result { + formatter.write_str("a ZosditMap") + } + + fn visit_seq(self, mut access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut map = ZosditMap::new(); + while let Some((interval, value)) = access.next_element()? { + map.insert_strict_back(interval, value).or(Err( + serde::de::Error::custom("intervals non-zero-overlap"), + ))?; + } + Ok(map) } - Ok(map) } }