extract addresses

This commit is contained in:
AF 2023-04-23 00:54:58 +00:00
parent 0cbb98ac84
commit 1aa0cff0b6
4 changed files with 72 additions and 65 deletions

View File

@ -0,0 +1,66 @@
use super::*;
/// Preferred way to parse [Point]s off of a [Serializer].
pub struct Addresses {
current: usize,
}
impl Addresses {
/// Read the next [Address].
pub fn next<'a>(
&mut self,
deserializer: &'a mut dyn Deserializer,
) -> Result<Address, &'a [u8]> {
let point = deserializer.read_n_const::<HASH_SIZE>()?;
let address = Address {
point,
index: self.current,
};
self.current += 1;
Ok(address)
}
/// Read the next [Point].
pub fn next_point<'a, 'b, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
&mut self,
deserializer: &'b mut dyn Deserializer,
resolver: Rc<dyn Resolver<'a, Ctx>>,
factory: A::Fctr,
) -> Result<Point<'a, Ctx, A>, &'b [u8]> {
Ok(Point::from_address(
self.next(deserializer)?,
factory,
resolver,
))
}
/// Start reading the [Address]es.
fn start() -> Self {
Addresses { current: 0 }
}
}
fn _parse_slice<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
factory: &A::Fctr,
slice: &[u8],
resolver: Rc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, A::Fctr> {
let mut deserializer = SliceDeserializer::from(slice);
let mentionable = factory.deserialize(&mut deserializer, resolver, &mut Addresses::start())?;
let tail = deserializer.read_all();
if tail.is_empty() {
Ok(mentionable)
} else {
Err(factory.unexpected_tail(tail))
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> ExtFactory<'a, Ctx> for F {
fn parse_slice(
&self,
slice: &[u8],
resolver: Rc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, Self> {
_parse_slice::<Ctx, F::Mtbl>(self, slice, resolver)
}
}

View File

@ -1,3 +1,6 @@
#[cfg(doc)]
use super::*;
/// Fixed [type@Hash] length. /// Fixed [type@Hash] length.
pub const HASH_SIZE: usize = 32; pub const HASH_SIZE: usize = 32;

View File

@ -40,68 +40,3 @@ pub trait Resolver<'a, Ctx: 'a + Context>: 'a {
/// with topology header ([`Mentionable::topology()`]) omitted. /// with topology header ([`Mentionable::topology()`]) omitted.
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>; fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx>;
} }
/// Preferred way to parse [Point]s off of a [Serializer].
pub struct Addresses {
current: usize,
}
impl Addresses {
/// Read the next [Address].
pub fn next<'a>(
&mut self,
deserializer: &'a mut dyn Deserializer,
) -> Result<Address, &'a [u8]> {
let point = deserializer.read_n_const::<HASH_SIZE>()?;
let address = Address {
point,
index: self.current,
};
self.current += 1;
Ok(address)
}
/// Read the next [Point].
pub fn next_point<'a, 'b, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
&mut self,
deserializer: &'b mut dyn Deserializer,
resolver: Rc<dyn Resolver<'a, Ctx>>,
factory: A::Fctr,
) -> Result<Point<'a, Ctx, A>, &'b [u8]> {
Ok(Point::from_address(
self.next(deserializer)?,
factory,
resolver,
))
}
/// Start reading the [Address]es.
fn start() -> Self {
Addresses { current: 0 }
}
}
fn _parse_slice<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
factory: &A::Fctr,
slice: &[u8],
resolver: Rc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, A::Fctr> {
let mut deserializer = SliceDeserializer::from(slice);
let mentionable = factory.deserialize(&mut deserializer, resolver, &mut Addresses::start())?;
let tail = deserializer.read_all();
if tail.is_empty() {
Ok(mentionable)
} else {
Err(factory.unexpected_tail(tail))
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> ExtFactory<'a, Ctx> for F {
fn parse_slice(
&self,
slice: &[u8],
resolver: Rc<dyn Resolver<'a, Ctx>>,
) -> ParseResult<'a, Ctx, Self> {
_parse_slice::<Ctx, F::Mtbl>(self, slice, resolver)
}
}

View File

@ -1,3 +1,6 @@
#[cfg(doc)]
use super::*;
/// Serialisation mechanism that is chosen over bytestring concatenation /// Serialisation mechanism that is chosen over bytestring concatenation
/// both for performance and simplicity. /// both for performance and simplicity.
/// ///