diff --git a/src/rcore.rs b/src/rcore.rs index a8581f7..9bd7d5e 100644 --- a/src/rcore.rs +++ b/src/rcore.rs @@ -76,7 +76,7 @@ pub trait Factory<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone { addresses: &mut Addresses, ) -> ParseResult<'a, Ctx, Self>; /// Called by finite stream parsers if there's any data left. - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError; + fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result; } pub type Mtbl<'a, Ctx, F> = >::Mtbl; diff --git a/src/rcore/addresses.rs b/src/rcore/addresses.rs index 33ca875..31aac60 100644 --- a/src/rcore/addresses.rs +++ b/src/rcore/addresses.rs @@ -51,7 +51,7 @@ fn _parse_slice<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>( if tail.is_empty() { Ok(mentionable) } else { - Err(factory.unexpected_tail(mentionable, tail)) + factory.extend(mentionable, tail) } } diff --git a/src/rstd/atomic.rs b/src/rstd/atomic.rs index 15f15fb..673e1c8 100644 --- a/src/rstd/atomic.rs +++ b/src/rstd/atomic.rs @@ -20,8 +20,8 @@ pub trait Atomic: 'static + Send + Sync + Send + Clone + Serializable { type AParseError: Error; /// Static equivalent of [`Factory::deserialize`]. fn a_deserialize(deserializer: &mut dyn Deserializer) -> Result; - /// Static equivalent of [`Factory::unexpected_tail`]. - fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError; + /// Static equivalent of [`Factory::extend`]. + fn a_extend(self, tail: &[u8]) -> Result; } fn _parse_slice(slice: &[u8]) -> Result { @@ -31,7 +31,7 @@ fn _parse_slice(slice: &[u8]) -> Result { if tail.is_empty() { Ok(atomic) } else { - Err(A::a_unexpected_tail(atomic, tail)) + A::a_extend(atomic, tail) } } diff --git a/src/rstd/atomic/atomic_object.rs b/src/rstd/atomic/atomic_object.rs index bb94d52..9b008e9 100644 --- a/src/rstd/atomic/atomic_object.rs +++ b/src/rstd/atomic/atomic_object.rs @@ -81,8 +81,8 @@ impl<'a, Ctx: Context<'a>, A: Atomic> Factory<'a, Ctx> for AtomicFactory { Ok(A::a_deserialize(deserializer)?.into()) } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - A::a_unexpected_tail(mentionable.atomic, tail) + fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result { + Ok(A::a_extend(mentionable.atomic, tail)?.into()) } } diff --git a/src/rstd/atomic/au64.rs b/src/rstd/atomic/au64.rs index 2c81293..52b0359 100644 --- a/src/rstd/atomic/au64.rs +++ b/src/rstd/atomic/au64.rs @@ -40,8 +40,8 @@ impl Atomic for u64 { Ok(u64::from_le_bytes(deserializer.read_n_const::<8>()?)) } - fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { - IntParseError::ExtraData(tail.len()) + fn a_extend(self, tail: &[u8]) -> Result { + Err(IntParseError::ExtraData(tail.len())) } } diff --git a/src/rstd/atomic/boolean.rs b/src/rstd/atomic/boolean.rs index 740bd81..b491309 100644 --- a/src/rstd/atomic/boolean.rs +++ b/src/rstd/atomic/boolean.rs @@ -52,8 +52,8 @@ impl Atomic for bool { } } - fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { - BooleanParseError::ExtraData(tail.len()) + fn a_extend(self, tail: &[u8]) -> Result { + Err(BooleanParseError::ExtraData(tail.len())) } } diff --git a/src/rstd/atomic/plain.rs b/src/rstd/atomic/plain.rs index 5da29f5..db71d16 100644 --- a/src/rstd/atomic/plain.rs +++ b/src/rstd/atomic/plain.rs @@ -35,11 +35,9 @@ impl Atomic for Plain { Ok(Plain::from_slice(deserializer.read_all())) } - fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { - panic!( - "Plain must use read_all, therefore there must not be any extra tail (received {} bytes).", - tail.len() - ) + fn a_extend(mut self, tail: &[u8]) -> Result { + self.data.extend_from_slice(tail); + Ok(self) } } diff --git a/src/rstd/collections/avl.rs b/src/rstd/collections/avl.rs index 8ded131..24c0a37 100644 --- a/src/rstd/collections/avl.rs +++ b/src/rstd/collections/avl.rs @@ -149,8 +149,16 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for AvlNodeFact Ok(AvlNode { l, r, key }) } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - AvlError::Key(self.0.unexpected_tail(mentionable.key, tail)) + fn extend( + &self, + mut mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result { + mentionable.key = self + .0 + .extend(mentionable.key, tail) + .map_err(AvlError::Key)?; + Ok(mentionable) } } @@ -177,7 +185,12 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for AvlTreeFact Ok(AvlTree { node, height }) } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - u64::a_unexpected_tail(mentionable.height, tail).into() + fn extend( + &self, + mut mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result { + mentionable.height = u64::a_extend(mentionable.height, tail)?; + Ok(mentionable) } } diff --git a/src/rstd/collections/stack.rs b/src/rstd/collections/stack.rs index 45bb292..fd4ff48 100644 --- a/src/rstd/collections/stack.rs +++ b/src/rstd/collections/stack.rs @@ -102,11 +102,16 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for StackNodeFa Ok(StackNode { rest, element }) } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - StackParseError::Element( - self.element_factory - .unexpected_tail(mentionable.element, tail), - ) + fn extend( + &self, + mut mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result { + mentionable.element = self + .element_factory + .extend(mentionable.element, tail) + .map_err(StackParseError::Element)?; + Ok(mentionable) } } diff --git a/src/rstd/inlining/static_pair.rs b/src/rstd/inlining/static_pair.rs index ecfd66d..939fdb7 100644 --- a/src/rstd/inlining/static_pair.rs +++ b/src/rstd/inlining/static_pair.rs @@ -151,10 +151,13 @@ impl<'a, Ctx: Context<'a>, SP: StaticPair<'a, Ctx>> Factory<'a, Ctx> }) } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { + fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result { let (_, fb) = SP::factories(&self.factory_data); - let (_, b) = mentionable.pair.into_elements(); - SP::from_error_b(&self.factory_data, fb.unexpected_tail(b, tail)) + let (a, b) = mentionable.pair.into_elements(); + match fb.extend(b, tail) { + Ok(b) => Ok(SP::from_parsed(&self.factory_data, a, b).into()), + Err(e) => Err(SP::from_error_b(&self.factory_data, e)), + } } } diff --git a/src/rstd/nullable.rs b/src/rstd/nullable.rs index 6011e6b..e075b34 100644 --- a/src/rstd/nullable.rs +++ b/src/rstd/nullable.rs @@ -70,8 +70,12 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for NullableFac }) } - fn unexpected_tail(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - PointParseError::WrongLength(HASH_SIZE + tail.len()) + fn extend( + &self, + _mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result { + Err(PointParseError::WrongLength(HASH_SIZE + tail.len())) } } diff --git a/src/rstd/point.rs b/src/rstd/point.rs index cd1535a..bd771e9 100644 --- a/src/rstd/point.rs +++ b/src/rstd/point.rs @@ -77,7 +77,11 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactor Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?) } - fn unexpected_tail(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - PointParseError::WrongLength(HASH_SIZE + tail.len()) + fn extend( + &self, + _mentionable: Self::Mtbl, + tail: &[u8], + ) -> Result { + Err(PointParseError::WrongLength(HASH_SIZE + tail.len())) } } diff --git a/src/rstd/typeless.rs b/src/rstd/typeless.rs index c113a01..45377b5 100644 --- a/src/rstd/typeless.rs +++ b/src/rstd/typeless.rs @@ -30,7 +30,11 @@ type TdeBox<'a, Ctx> = Box>; trait Tut<'a, Ctx: Context<'a>>: 'a + Send + Sync { fn clone_box(&self) -> TutBox<'a, Ctx>; - fn ut(&self, mentionable: TypelessMentionable<'a, Ctx>, tail: &[u8]) -> TypelessError<'a>; + fn xt( + &self, + mentionable: TypelessMentionable<'a, Ctx>, + tail: &[u8], + ) -> Result, TypelessError<'a>>; } type TutBox<'a, Ctx> = Box>; @@ -38,7 +42,7 @@ type TutBox<'a, Ctx> = Box>; /// See [`Point::typeless`]/[`TypelessMentionable`]. pub struct TypelessFactory<'a, Ctx: Context<'a>> { t_deserialize: TdeBox<'a, Ctx>, - t_unexpected_tail: TutBox<'a, Ctx>, + t_extend: TutBox<'a, Ctx>, } impl<'a, Ctx: Context<'a>> Serializable for TypelessMentionable<'a, Ctx> { @@ -69,7 +73,7 @@ impl<'a, Ctx: Context<'a>> Clone for TypelessFactory<'a, Ctx> { fn clone(&self) -> Self { Self { t_deserialize: self.t_deserialize.clone_box(), - t_unexpected_tail: self.t_unexpected_tail.clone_box(), + t_extend: self.t_extend.clone_box(), } } } @@ -103,8 +107,8 @@ impl<'a, Ctx: Context<'a>> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> { } } - fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { - self.t_unexpected_tail.ut(mentionable, tail) + fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result { + self.t_extend.xt(mentionable, tail) } } @@ -157,14 +161,21 @@ where Box::new(self.clone()) } - fn ut(&self, mentionable: TypelessMentionable<'a, Ctx>, tail: &[u8]) -> TypelessError<'a> { - TypelessError::from_typed(self.unexpected_tail( + fn xt( + &self, + mentionable: TypelessMentionable<'a, Ctx>, + tail: &[u8], + ) -> Result, TypelessError<'a>> { + self.extend( match mentionable.cast(self.clone()) { Ok(m) => m, - Err(e) => return TypelessError::from_typed(e), + Err(e) => return Err(TypelessError::from_typed(e)), }, tail, - )) + ) + .map_err(TypelessError::from_typed) + .map(Rc::new) + .map(TypelessMentionable::from_typed) } } @@ -175,7 +186,7 @@ where pub fn from_typed>(factory: F) -> Self { TypelessFactory { t_deserialize: Box::new(factory.clone()), - t_unexpected_tail: Box::new(factory), + t_extend: Box::new(factory), } } }