Factory::extend

This commit is contained in:
AF 2023-06-16 07:06:43 +00:00
parent 8ecc4678f7
commit 5081166bca
13 changed files with 80 additions and 42 deletions

View File

@ -76,7 +76,7 @@ pub trait Factory<'a, Ctx: Context<'a>>: 'a + Send + Sync + Clone {
addresses: &mut Addresses, addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self>; ) -> ParseResult<'a, Ctx, Self>;
/// Called by finite stream parsers if there's any data left. /// 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<Self::Mtbl, Self::ParseError>;
} }
pub type Mtbl<'a, Ctx, F> = <F as Factory<'a, Ctx>>::Mtbl; pub type Mtbl<'a, Ctx, F> = <F as Factory<'a, Ctx>>::Mtbl;

View File

@ -51,7 +51,7 @@ fn _parse_slice<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
if tail.is_empty() { if tail.is_empty() {
Ok(mentionable) Ok(mentionable)
} else { } else {
Err(factory.unexpected_tail(mentionable, tail)) factory.extend(mentionable, tail)
} }
} }

View File

@ -20,8 +20,8 @@ pub trait Atomic: 'static + Send + Sync + Send + Clone + Serializable {
type AParseError: Error; type AParseError: Error;
/// Static equivalent of [`Factory::deserialize`]. /// Static equivalent of [`Factory::deserialize`].
fn a_deserialize(deserializer: &mut dyn Deserializer) -> Result<Self, Self::AParseError>; fn a_deserialize(deserializer: &mut dyn Deserializer) -> Result<Self, Self::AParseError>;
/// Static equivalent of [`Factory::unexpected_tail`]. /// Static equivalent of [`Factory::extend`].
fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError; fn a_extend(self, tail: &[u8]) -> Result<Self, Self::AParseError>;
} }
fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::AParseError> { fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::AParseError> {
@ -31,7 +31,7 @@ fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::AParseError> {
if tail.is_empty() { if tail.is_empty() {
Ok(atomic) Ok(atomic)
} else { } else {
Err(A::a_unexpected_tail(atomic, tail)) A::a_extend(atomic, tail)
} }
} }

View File

@ -81,8 +81,8 @@ impl<'a, Ctx: Context<'a>, A: Atomic> Factory<'a, Ctx> for AtomicFactory<A> {
Ok(A::a_deserialize(deserializer)?.into()) Ok(A::a_deserialize(deserializer)?.into())
} }
fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result<Self::Mtbl, Self::ParseError> {
A::a_unexpected_tail(mentionable.atomic, tail) Ok(A::a_extend(mentionable.atomic, tail)?.into())
} }
} }

View File

@ -40,8 +40,8 @@ impl Atomic for u64 {
Ok(u64::from_le_bytes(deserializer.read_n_const::<8>()?)) Ok(u64::from_le_bytes(deserializer.read_n_const::<8>()?))
} }
fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { fn a_extend(self, tail: &[u8]) -> Result<Self, Self::AParseError> {
IntParseError::ExtraData(tail.len()) Err(IntParseError::ExtraData(tail.len()))
} }
} }

View File

@ -52,8 +52,8 @@ impl Atomic for bool {
} }
} }
fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { fn a_extend(self, tail: &[u8]) -> Result<Self, Self::AParseError> {
BooleanParseError::ExtraData(tail.len()) Err(BooleanParseError::ExtraData(tail.len()))
} }
} }

View File

@ -35,11 +35,9 @@ impl Atomic for Plain {
Ok(Plain::from_slice(deserializer.read_all())) Ok(Plain::from_slice(deserializer.read_all()))
} }
fn a_unexpected_tail(self, tail: &[u8]) -> Self::AParseError { fn a_extend(mut self, tail: &[u8]) -> Result<Self, Self::AParseError> {
panic!( self.data.extend_from_slice(tail);
"Plain must use read_all, therefore there must not be any extra tail (received {} bytes).", Ok(self)
tail.len()
)
} }
} }

View File

@ -149,8 +149,16 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for AvlNodeFact
Ok(AvlNode { l, r, key }) Ok(AvlNode { l, r, key })
} }
fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { fn extend(
AvlError::Key(self.0.unexpected_tail(mentionable.key, tail)) &self,
mut mentionable: Self::Mtbl,
tail: &[u8],
) -> Result<Self::Mtbl, Self::ParseError> {
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 }) Ok(AvlTree { node, height })
} }
fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { fn extend(
u64::a_unexpected_tail(mentionable.height, tail).into() &self,
mut mentionable: Self::Mtbl,
tail: &[u8],
) -> Result<Self::Mtbl, Self::ParseError> {
mentionable.height = u64::a_extend(mentionable.height, tail)?;
Ok(mentionable)
} }
} }

View File

@ -102,11 +102,16 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for StackNodeFa
Ok(StackNode { rest, element }) Ok(StackNode { rest, element })
} }
fn unexpected_tail(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { fn extend(
StackParseError::Element( &self,
self.element_factory mut mentionable: Self::Mtbl,
.unexpected_tail(mentionable.element, tail), tail: &[u8],
) ) -> Result<Self::Mtbl, Self::ParseError> {
mentionable.element = self
.element_factory
.extend(mentionable.element, tail)
.map_err(StackParseError::Element)?;
Ok(mentionable)
} }
} }

View File

@ -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<Self::Mtbl, Self::ParseError> {
let (_, fb) = SP::factories(&self.factory_data); let (_, fb) = SP::factories(&self.factory_data);
let (_, b) = mentionable.pair.into_elements(); let (a, b) = mentionable.pair.into_elements();
SP::from_error_b(&self.factory_data, fb.unexpected_tail(b, tail)) 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)),
}
} }
} }

View File

@ -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 { fn extend(
PointParseError::WrongLength(HASH_SIZE + tail.len()) &self,
_mentionable: Self::Mtbl,
tail: &[u8],
) -> Result<Self::Mtbl, Self::ParseError> {
Err(PointParseError::WrongLength(HASH_SIZE + tail.len()))
} }
} }

View File

@ -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())?) Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?)
} }
fn unexpected_tail(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> Self::ParseError { fn extend(
PointParseError::WrongLength(HASH_SIZE + tail.len()) &self,
_mentionable: Self::Mtbl,
tail: &[u8],
) -> Result<Self::Mtbl, Self::ParseError> {
Err(PointParseError::WrongLength(HASH_SIZE + tail.len()))
} }
} }

View File

@ -30,7 +30,11 @@ type TdeBox<'a, Ctx> = Box<dyn Tde<'a, Ctx>>;
trait Tut<'a, Ctx: Context<'a>>: 'a + Send + Sync { trait Tut<'a, Ctx: Context<'a>>: 'a + Send + Sync {
fn clone_box(&self) -> TutBox<'a, Ctx>; 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<TypelessMentionable<'a, Ctx>, TypelessError<'a>>;
} }
type TutBox<'a, Ctx> = Box<dyn Tut<'a, Ctx>>; type TutBox<'a, Ctx> = Box<dyn Tut<'a, Ctx>>;
@ -38,7 +42,7 @@ type TutBox<'a, Ctx> = Box<dyn Tut<'a, Ctx>>;
/// See [`Point::typeless`]/[`TypelessMentionable`]. /// See [`Point::typeless`]/[`TypelessMentionable`].
pub struct TypelessFactory<'a, Ctx: Context<'a>> { pub struct TypelessFactory<'a, Ctx: Context<'a>> {
t_deserialize: TdeBox<'a, Ctx>, 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> { 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 { fn clone(&self) -> Self {
Self { Self {
t_deserialize: self.t_deserialize.clone_box(), 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 { fn extend(&self, mentionable: Self::Mtbl, tail: &[u8]) -> Result<Self::Mtbl, Self::ParseError> {
self.t_unexpected_tail.ut(mentionable, tail) self.t_extend.xt(mentionable, tail)
} }
} }
@ -157,14 +161,21 @@ where
Box::new(self.clone()) Box::new(self.clone())
} }
fn ut(&self, mentionable: TypelessMentionable<'a, Ctx>, tail: &[u8]) -> TypelessError<'a> { fn xt(
TypelessError::from_typed(self.unexpected_tail( &self,
mentionable: TypelessMentionable<'a, Ctx>,
tail: &[u8],
) -> Result<TypelessMentionable<'a, Ctx>, TypelessError<'a>> {
self.extend(
match mentionable.cast(self.clone()) { match mentionable.cast(self.clone()) {
Ok(m) => m, Ok(m) => m,
Err(e) => return TypelessError::from_typed(e), Err(e) => return Err(TypelessError::from_typed(e)),
}, },
tail, tail,
)) )
.map_err(TypelessError::from_typed)
.map(Rc::new)
.map(TypelessMentionable::from_typed)
} }
} }
@ -175,7 +186,7 @@ where
pub fn from_typed<F: Factory<'a, Ctx>>(factory: F) -> Self { pub fn from_typed<F: Factory<'a, Ctx>>(factory: F) -> Self {
TypelessFactory { TypelessFactory {
t_deserialize: Box::new(factory.clone()), t_deserialize: Box::new(factory.clone()),
t_unexpected_tail: Box::new(factory), t_extend: Box::new(factory),
} }
} }
} }