From 24186d3e5eda13fb1865b0708ee52c9ca8f12a0e Mon Sep 17 00:00:00 2001 From: kirk Date: Sat, 16 Mar 2024 18:57:41 +0000 Subject: [PATCH] fix serialization bounds --- src/collections/ordered_array_like.rs | 141 +++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 4 deletions(-) diff --git a/src/collections/ordered_array_like.rs b/src/collections/ordered_array_like.rs index 8f06ad6..6a0e51f 100644 --- a/src/collections/ordered_array_like.rs +++ b/src/collections/ordered_array_like.rs @@ -1,9 +1,6 @@ -#[cfg(feature = "nanoserde")] -use nanoserde::{DeBin, SerBin}; use std::fmt::Debug; #[derive(Clone, Copy, Debug)] -#[cfg_attr(feature = "nanoserde", derive(SerBin))] #[cfg_attr(feature = "serde", derive(serde::Serialize))] pub(crate) enum OrderedArrayLikeChangeRef<'a, T> { Replace(&'a T, usize), @@ -14,7 +11,6 @@ pub(crate) enum OrderedArrayLikeChangeRef<'a, T> { } #[derive(Debug, Clone)] -#[cfg_attr(feature = "nanoserde", derive(SerBin, DeBin))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub(crate) enum OrderedArrayLikeChangeOwned { Replace(T, usize), @@ -70,9 +66,11 @@ impl OrderedArrayLikeChangeOwned { } #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct OrderedArrayLikeDiffOwned(Vec>); #[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] pub struct OrderedArrayLikeDiffRef<'src, T>(Vec>); impl<'src, T: Clone> From> for OrderedArrayLikeDiffOwned { @@ -208,6 +206,141 @@ where Box::new(ret.into_iter()) } +#[cfg(feature = "nanoserde")] +mod nanoserde_impls { + use super::*; + use nanoserde::{DeBin, SerBin}; + + impl OrderedArrayLikeChangeOwned { + #[inline] + fn nanoserde_discriminant(&self) -> u8 { + match self { + OrderedArrayLikeChangeOwned::Replace(_, _) => 0, + OrderedArrayLikeChangeOwned::Insert(_, _) => 1, + OrderedArrayLikeChangeOwned::Delete(_, _) => 2, + OrderedArrayLikeChangeOwned::Swap(_, _) => 3, + } + } + } + + impl OrderedArrayLikeChangeRef<'_, T> { + #[inline] + fn nanoserde_discriminant(&self) -> u8 { + match self { + OrderedArrayLikeChangeRef::Replace(_, _) => 0, + OrderedArrayLikeChangeRef::Insert(_, _) => 1, + OrderedArrayLikeChangeRef::Delete(_, _) => 2, + OrderedArrayLikeChangeRef::Swap(_, _) => 3, + } + } + } + + impl SerBin for OrderedArrayLikeChangeOwned { + fn ser_bin(&self, output: &mut Vec) { + match self { + OrderedArrayLikeChangeOwned::Replace(val, idx) => { + self.nanoserde_discriminant().ser_bin(output); + val.ser_bin(output); + idx.ser_bin(output); + } + OrderedArrayLikeChangeOwned::Insert(val, idx) => { + self.nanoserde_discriminant().ser_bin(output); + val.ser_bin(output); + idx.ser_bin(output); + } + OrderedArrayLikeChangeOwned::Delete(idx, opt_start) => { + self.nanoserde_discriminant().ser_bin(output); + idx.ser_bin(output); + opt_start.ser_bin(output); + } + OrderedArrayLikeChangeOwned::Swap(l, r) => { + self.nanoserde_discriminant().ser_bin(output); + l.ser_bin(output); + r.ser_bin(output); + } + } + } + } + + impl SerBin for OrderedArrayLikeChangeRef<'_, T> { + fn ser_bin(&self, output: &mut Vec) { + match self { + OrderedArrayLikeChangeRef::Replace(val, idx) => { + self.nanoserde_discriminant().ser_bin(output); + val.ser_bin(output); + idx.ser_bin(output); + } + OrderedArrayLikeChangeRef::Insert(val, idx) => { + self.nanoserde_discriminant().ser_bin(output); + val.ser_bin(output); + idx.ser_bin(output); + } + OrderedArrayLikeChangeRef::Delete(idx, opt_start) => { + self.nanoserde_discriminant().ser_bin(output); + idx.ser_bin(output); + opt_start.ser_bin(output); + } + OrderedArrayLikeChangeRef::Swap(l, r) => { + self.nanoserde_discriminant().ser_bin(output); + l.ser_bin(output); + r.ser_bin(output); + } + } + } + } + + impl DeBin for OrderedArrayLikeChangeOwned { + fn de_bin(offset: &mut usize, bytes: &[u8]) -> Result { + match ::de_bin(offset, bytes)? { + 0 => { + let val = ::de_bin(offset, bytes)?; + let idx = ::de_bin(offset, bytes)?; + Ok(OrderedArrayLikeChangeOwned::Replace(val, idx)) + } + 1 => { + let val = ::de_bin(offset, bytes)?; + let idx = ::de_bin(offset, bytes)?; + Ok(OrderedArrayLikeChangeOwned::Insert(val, idx)) + } + 2 => { + let idx = ::de_bin(offset, bytes)?; + let opt_start = as DeBin>::de_bin(offset, bytes)?; + Ok(OrderedArrayLikeChangeOwned::Delete(idx, opt_start)) + } + 3 => { + let l = ::de_bin(offset, bytes)?; + let r = ::de_bin(offset, bytes)?; + Ok(OrderedArrayLikeChangeOwned::Swap(l, r)) + } + _ => Err(nanoserde::DeBinErr { + o: *offset - 1, + l: 1, + s: 1, + }), + } + } + } + + impl SerBin for OrderedArrayLikeDiffRef<'_, T> { + fn ser_bin(&self, output: &mut Vec) { + self.0.ser_bin(output); + } + } + + impl SerBin for OrderedArrayLikeDiffOwned { + fn ser_bin(&self, output: &mut Vec) { + self.0.ser_bin(output); + } + } + + impl DeBin for OrderedArrayLikeDiffOwned { + fn de_bin(offset: &mut usize, bytes: &[u8]) -> Result { + let ret = as DeBin>::de_bin(offset, bytes)?; + Ok(Self(ret)) + } + } +} + #[cfg(test)] mod test { use std::collections::LinkedList;