diff --git a/src/gtree.rs b/src/gtree.rs index 5c07606..0a3c324 100644 --- a/src/gtree.rs +++ b/src/gtree.rs @@ -100,7 +100,6 @@ const _NODE_IDX_LAYOUT_CHECK: usize = { /// /// TODO: finish describing the data structure. #[derive(Clone, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, ::serde::Deserialize))] pub(crate) struct Gtree { /// The internal nodes of the Gtree. /// @@ -130,7 +129,6 @@ pub(crate) struct Gtree { /// It can be passed to [`Gtree::inode()`] and [`Gtree::inode_mut()`] to /// get access to the inode. #[derive(Clone, Copy, PartialEq, Eq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct InodeIdx(usize); impl InodeIdx { @@ -159,7 +157,6 @@ impl InodeIdx { /// A stable identifier for a particular leaf in the Gtree. #[derive(Eq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub struct LeafIdx { idx: usize, _pd: PhantomData, @@ -201,7 +198,6 @@ impl LeafIdx { /// two leaf nodes in the tree, much like a line cursor identifies a position /// between two characters in a text editor. #[derive(PartialEq, Eq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] struct Cursor { /// The index of the leaf node that comes *after* the cursor. There always /// is one because the cursor is never parked after the last leafof the @@ -2733,7 +2729,6 @@ impl Inode { /// A leaf node of the Gtree. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct Lnode { /// The value of this leaf node. value: Leaf, @@ -3618,9 +3613,9 @@ pub(crate) mod encode { let (num_children, buf) = usize::decode(buf)?; let (has_leaves, mut buf) = bool::decode(buf)?; let mut children = [NodeIdx::dangling(); N]; - for idx in 0..num_children { + for idx in &mut children[..num_children] { let (node_idx, new_buf) = NodeIdx::decode(buf)?; - children[idx] = node_idx; + *idx = node_idx; buf = new_buf; } let this = @@ -3629,201 +3624,3 @@ pub(crate) mod encode { } } } - -#[cfg(feature = "encode")] -mod inode_serde { - use serde::ser::SerializeMap; - use serde::{de, ser}; - - use super::*; - - impl ser::Serialize for Inode - where - Length: ser::Serialize, - { - fn serialize( - &self, - serializer: S, - ) -> Result { - let mut map = serializer.serialize_map(Some(5))?; - - map.serialize_entry("tot_len", &self.tot_len)?; - map.serialize_entry("parent", &self.parent)?; - map.serialize_entry("num_children", &self.num_children)?; - map.serialize_entry("has_leaves", &self.has_leaves)?; - - match self.children() { - Either::Internal(inode_idxs) => { - map.serialize_entry("children", inode_idxs)?; - }, - - Either::Leaf(leaf_idxs) => { - map.serialize_entry("children", leaf_idxs)?; - }, - } - - map.end() - } - } - - impl<'de, const N: usize, L: Leaf> de::Deserialize<'de> for Inode - where - Length: de::Deserialize<'de>, - { - fn deserialize>( - deserializer: D, - ) -> Result { - struct InodeVisitor(PhantomData); - - impl<'de, const N: usize, L> de::Visitor<'de> for InodeVisitor - where - L: Leaf, - Length: de::Deserialize<'de>, - { - type Value = Inode; - - #[inline] - fn expecting( - &self, - formatter: &mut core::fmt::Formatter, - ) -> core::fmt::Result { - formatter.write_str("a map representing an Inode") - } - - #[inline] - fn visit_map>( - self, - mut map: V, - ) -> Result { - let mut tot_len = None; - let mut parent = None; - let mut num_children = None; - let mut has_leaves = None; - let mut children_vec = None; - - while let Some(key) = map.next_key()? { - match key { - "tot_len" => { - if tot_len.is_some() { - return Err(de::Error::duplicate_field( - "tot_len", - )); - } - tot_len = Some(map.next_value()?); - }, - - "parent" => { - if parent.is_some() { - return Err(de::Error::duplicate_field( - "parent", - )); - } - parent = Some(map.next_value()?); - }, - - "num_children" => { - if num_children.is_some() { - return Err(de::Error::duplicate_field( - "num_children", - )); - } - num_children = Some(map.next_value()?); - }, - - "has_leaves" => { - if has_leaves.is_some() { - return Err(de::Error::duplicate_field( - "has_leaves", - )); - } - has_leaves = Some(map.next_value()?); - }, - - "children" => { - if children_vec.is_some() { - return Err(de::Error::duplicate_field( - "children", - )); - } - children_vec = - Some(map.next_value::>()?); - }, - - _ => { - return Err(de::Error::unknown_field( - key, - &[ - "tot_len", - "parent", - "num_children", - "has_leaves", - "children", - ], - )); - }, - } - } - - let tot_len = tot_len - .ok_or_else(|| de::Error::missing_field("tot_len"))?; - - let parent = parent - .ok_or_else(|| de::Error::missing_field("parent"))?; - - let num_children = num_children.ok_or_else(|| { - de::Error::missing_field("num_children") - })?; - - let has_leaves = has_leaves.ok_or_else(|| { - de::Error::missing_field("has_leaves") - })?; - - let children_slice = children_vec - .ok_or_else(|| de::Error::missing_field("children"))?; - - if children_slice.len() != num_children { - return Err(de::Error::invalid_length( - children_slice.len(), - &num_children.to_string().as_str(), - )); - } - - if children_slice.len() > N { - return Err(de::Error::invalid_length( - children_slice.len(), - &format!("no more than {N}").as_str(), - )); - } - - let mut children = [NodeIdx::dangling(); N]; - - if has_leaves { - for (i, child_idx) in - children_slice.into_iter().enumerate() - { - children[i] = - NodeIdx::from_leaf(LeafIdx::new(child_idx)); - } - } else { - for (i, child_idx) in - children_slice.into_iter().enumerate() - { - children[i] = - NodeIdx::from_internal(InodeIdx(child_idx)); - } - } - - Ok(Inode { - tot_len, - parent, - num_children, - has_leaves, - children, - }) - } - } - - deserializer.deserialize_map(InodeVisitor(PhantomData)) - } - } -} diff --git a/src/run_indices.rs b/src/run_indices.rs index 032f7af..17696bd 100644 --- a/src/run_indices.rs +++ b/src/run_indices.rs @@ -6,7 +6,6 @@ use crate::*; /// A data structure used when merging remote edits to efficiently map /// an [`Anchor`] to the [`LeafIdx`] of the [`EditRun`] that contains it. #[derive(Clone, Default, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct RunIndices { map: ReplicaIdMap, } @@ -74,7 +73,6 @@ impl RunIndices { /// Contains the [`LeafIdx`]s of all the [`EditRun`]s that have been inserted /// by a given `Replica`. #[derive(Clone, Default, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct ReplicaIndices { /// The [`Fragments`] are stored sequentially and in order of insertion. /// @@ -232,10 +230,6 @@ mod fragments { /// The `Fragment`s that an insertion run has been fragmented into. #[derive(Clone, PartialEq)] - #[cfg_attr( - feature = "encode", - derive(serde::Serialize, serde::Deserialize) - )] pub(crate) enum Fragments { /// The first `INLINE` fragments are stored inline to avoid /// allocating a `Gtree` for runs that are not heavily fragmented. @@ -623,141 +617,10 @@ mod fragments { crate::insert_in_slice(fragments, new_fragment, idx + 1); } } - - #[cfg(feature = "encode")] - mod array_serde { - use serde::ser::SerializeMap; - use serde::{de, ser}; - - use super::*; - - impl ser::Serialize for Array { - fn serialize( - &self, - serializer: S, - ) -> Result { - let mut map = serializer.serialize_map(Some(3))?; - map.serialize_entry("fragments", self.fragments())?; - map.serialize_entry("len", &self.len)?; - map.serialize_entry("total_len", &self.total_len)?; - map.end() - } - } - - impl<'de, const N: usize> de::Deserialize<'de> for Array { - fn deserialize>( - deserializer: D, - ) -> Result { - struct ArrayVisitor; - - impl<'de, const N: usize> de::Visitor<'de> for ArrayVisitor { - type Value = Array; - - #[inline] - fn expecting( - &self, - formatter: &mut core::fmt::Formatter, - ) -> core::fmt::Result { - formatter.write_str("a map representing an Array") - } - - #[inline] - fn visit_map>( - self, - mut map: V, - ) -> Result { - let mut len = None; - let mut total_len = None; - let mut fragments_vec = None; - - while let Some(key) = map.next_key()? { - match key { - "len" => { - if len.is_some() { - return Err( - de::Error::duplicate_field("len"), - ); - } - len = Some(map.next_value()?); - }, - - "total_len" => { - if total_len.is_some() { - return Err( - de::Error::duplicate_field( - "total_len", - ), - ); - } - total_len = Some(map.next_value()?); - }, - - "fragments" => { - if fragments_vec.is_some() { - return Err( - de::Error::duplicate_field( - "fragments", - ), - ); - } - fragments_vec = Some( - map.next_value::>()?, - ); - }, - - _ => { - return Err(de::Error::unknown_field( - key, - &["fragments", "len", "total_len"], - )); - }, - } - } - - let len = len - .ok_or_else(|| de::Error::missing_field("len"))?; - - let total_len = total_len.ok_or_else(|| { - de::Error::missing_field("total_len") - })?; - - let fragments_vec = - fragments_vec.ok_or_else(|| { - de::Error::missing_field("fragments") - })?; - - if fragments_vec.len() != len { - return Err(de::Error::invalid_length( - fragments_vec.len(), - &len.to_string().as_str(), - )); - } - - if fragments_vec.len() > N { - return Err(de::Error::invalid_length( - fragments_vec.len(), - &format!("no more than {N}").as_str(), - )); - } - - let mut fragments = [Fragment::null(); N]; - - fragments[..len] - .copy_from_slice(fragments_vec.as_slice()); - - Ok(Array { fragments, len, total_len }) - } - } - - deserializer.deserialize_map(ArrayVisitor) - } - } - } } /// The length and [`LeafIdx`] of a fragment of a single insertion run. #[derive(Copy, Clone, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct Fragment { len: Length, idx: LeafIdx, diff --git a/src/run_tree.rs b/src/run_tree.rs index fd83279..da34b5a 100644 --- a/src/run_tree.rs +++ b/src/run_tree.rs @@ -10,7 +10,6 @@ const RUN_TREE_ARITY: usize = 32; type Gtree = crate::Gtree; #[derive(Clone, Debug, PartialEq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct RunTree { /// The tree of runs. gtree: Gtree, @@ -844,7 +843,6 @@ impl RunTree { /// TODO: docs #[derive(Clone, PartialEq, Eq)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct EditRun { /// TODO: docs text: Text, @@ -1419,3 +1417,9 @@ mod encode { } } } + +#[cfg(feature = "serde")] +mod serde { + crate::encode::impl_serialize!(super::RunTree); + crate::encode::impl_deserialize!(super::RunTree); +} diff --git a/src/utils.rs b/src/utils.rs index d826486..5e1acf9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -5,7 +5,6 @@ use core::ops::{Add, Range as StdRange, RangeBounds, Sub}; use crate::Length; #[derive(Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "encode", derive(serde::Serialize, serde::Deserialize))] pub(crate) struct Range { pub start: T, pub end: T,