addresses moved to core
This commit is contained in:
parent
8ebe30cd65
commit
29d0eb3ee2
185
src/core.rs
185
src/core.rs
@ -2,7 +2,7 @@
|
|||||||
//! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python.
|
//! Brings [`Mentionable`]/[`Factory`]/[`Origin`] concepts from the original implementation in Python.
|
||||||
//! Allows for more generic behaviour via [`Context`], as opposed to original async-only.
|
//! Allows for more generic behaviour via [`Context`], as opposed to original async-only.
|
||||||
|
|
||||||
use std::{error::Error, fmt::Display, rc::Rc};
|
use std::{cmp::min, error::Error, fmt::Display, rc::Rc};
|
||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
@ -155,6 +155,7 @@ pub trait Factory<'a, Ctx: 'a + Context>: Clone + 'a {
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
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, tail: &[u8]) -> Self::ParseError;
|
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError;
|
||||||
@ -231,6 +232,22 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
|
|||||||
LocalOrigin::from(mentionable),
|
LocalOrigin::from(mentionable),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make a [Point] from an [Address].
|
||||||
|
pub fn from_address(
|
||||||
|
address: Address,
|
||||||
|
factory: A::Fctr,
|
||||||
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
) -> Self {
|
||||||
|
Point {
|
||||||
|
point: address.point,
|
||||||
|
origin: Rc::new(ResolverOrigin {
|
||||||
|
r_factory: factory,
|
||||||
|
r_address: address,
|
||||||
|
r_resolver: resolver,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
|
||||||
@ -251,8 +268,8 @@ pub struct TypelessMentionable<'a, Ctx: 'a + Context> {
|
|||||||
|
|
||||||
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
|
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
|
||||||
|
|
||||||
type TypelessDeserialize<'a, Ctx> =
|
type TypelessDeserialize<'a, Ctx> = dyn 'a
|
||||||
dyn 'a + Fn(&mut dyn Deserializer, Rc<dyn Resolver<'a, Ctx>>) -> TypelessParsed<'a, Ctx>;
|
+ Fn(&mut dyn Deserializer, Rc<dyn Resolver<'a, Ctx>>, &mut Addresses) -> TypelessParsed<'a, Ctx>;
|
||||||
|
|
||||||
type TypelessUnexpectedTail<'a> = dyn 'a + Fn(&[u8]) -> TypelessError<'a>;
|
type TypelessUnexpectedTail<'a> = dyn 'a + Fn(&[u8]) -> TypelessError<'a>;
|
||||||
|
|
||||||
@ -318,8 +335,9 @@ impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> {
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
match (self.t_deserialize)(deserializer, resolver) {
|
match (self.t_deserialize)(deserializer, resolver, addresses) {
|
||||||
Ok(mentionable) => Ok(mentionable),
|
Ok(mentionable) => Ok(mentionable),
|
||||||
Err(error) => Err(TypelessError(error)),
|
Err(error) => Err(TypelessError(error)),
|
||||||
}
|
}
|
||||||
@ -348,8 +366,8 @@ impl<'a, Ctx: 'a + Context> TypelessFactory<'a, Ctx> {
|
|||||||
pub fn from_typed<F: Factory<'a, Ctx>>(factory: F) -> Self {
|
pub fn from_typed<F: Factory<'a, Ctx>>(factory: F) -> Self {
|
||||||
let tail_factory = factory.clone();
|
let tail_factory = factory.clone();
|
||||||
TypelessFactory {
|
TypelessFactory {
|
||||||
t_deserialize: Rc::new(move |deserializer, resolver| {
|
t_deserialize: Rc::new(move |deserializer, resolver, addresses| {
|
||||||
match factory.deserialize(deserializer, resolver) {
|
match factory.deserialize(deserializer, resolver, addresses) {
|
||||||
Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))),
|
Ok(mentionable) => Ok(TypelessMentionable::from_typed(Rc::new(mentionable))),
|
||||||
Err(error) => Err(Box::new(error)),
|
Err(error) => Err(Box::new(error)),
|
||||||
}
|
}
|
||||||
@ -366,3 +384,158 @@ impl<'a> TypelessError<'a> {
|
|||||||
TypelessError(Box::new(error))
|
TypelessError(Box::new(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ExtDeserializer {
|
||||||
|
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: ?Sized + Deserializer> ExtDeserializer for D {
|
||||||
|
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]> {
|
||||||
|
let slice = self.read_n(N);
|
||||||
|
match slice.try_into() {
|
||||||
|
Ok(array) => Ok(array),
|
||||||
|
Err(_) => Err(slice),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ResolverOrigin<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> {
|
||||||
|
r_factory: F,
|
||||||
|
r_address: Address,
|
||||||
|
r_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _resolve_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
|
||||||
|
origin: Rc<ResolverOrigin<'a, Ctx, A::Fctr>>,
|
||||||
|
) -> Resolution<'a, Ctx, A> {
|
||||||
|
let resolution = origin.r_resolver.clone().resolve(origin.r_address);
|
||||||
|
Ctx::T::fmap(
|
||||||
|
move |resolved| match resolved {
|
||||||
|
Ok((src, resolver)) => match origin.r_factory.parse_slice(&src, resolver) {
|
||||||
|
Ok(mentionable) => Ok(Rc::new(mentionable)),
|
||||||
|
Err(parse_error) => Err(ResolutionError::Parse(parse_error)),
|
||||||
|
},
|
||||||
|
Err(lookup_error) => Err(ResolutionError::Lookup(lookup_error)),
|
||||||
|
},
|
||||||
|
resolution,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrigin<'a, Ctx, F> {
|
||||||
|
type Mtbl = F::Mtbl;
|
||||||
|
|
||||||
|
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
|
||||||
|
self.r_factory.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
|
||||||
|
_resolve_origin(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ExtFactory<'a, Ctx: 'a + Context>: Factory<'a, Ctx> {
|
||||||
|
fn parse_slice(
|
||||||
|
&self,
|
||||||
|
slice: &[u8],
|
||||||
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
) -> ParseResult<'a, Ctx, Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SliceDeserializer<'a> {
|
||||||
|
slice: &'a [u8],
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a [u8]> for SliceDeserializer<'a> {
|
||||||
|
fn from(value: &'a [u8]) -> Self {
|
||||||
|
SliceDeserializer {
|
||||||
|
slice: value,
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Deserializer for SliceDeserializer<'a> {
|
||||||
|
fn read_n(&mut self, n: usize) -> &[u8] {
|
||||||
|
let (left, right) = self.slice.split_at(min(n, self.slice.len()));
|
||||||
|
self.slice = right;
|
||||||
|
self.pos += left.len();
|
||||||
|
left
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_all(&mut self) -> &[u8] {
|
||||||
|
let left = self.slice;
|
||||||
|
self.slice = &[];
|
||||||
|
self.pos += left.len();
|
||||||
|
left
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tell(&self) -> usize {
|
||||||
|
self.pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
170
src/std.rs
170
src/std.rs
@ -1,10 +1,11 @@
|
|||||||
|
//! Standard extensions to [`crate::core`].
|
||||||
|
|
||||||
pub mod atomic;
|
pub mod atomic;
|
||||||
pub mod cast;
|
pub mod cast;
|
||||||
pub mod collections;
|
pub mod collections;
|
||||||
pub mod inlining;
|
pub mod inlining;
|
||||||
pub mod nullable;
|
pub mod nullable;
|
||||||
|
|
||||||
use std::cmp::min;
|
|
||||||
use std::{error::Error, fmt::Display, rc::Rc};
|
use std::{error::Error, fmt::Display, rc::Rc};
|
||||||
|
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
@ -161,62 +162,12 @@ impl From<&[u8]> for PointParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
|
|
||||||
fn from_address(
|
|
||||||
address: Address,
|
|
||||||
factory: A::Fctr,
|
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
|
||||||
) -> Self {
|
|
||||||
Point {
|
|
||||||
point: address.point,
|
|
||||||
origin: Rc::new(ResolverOrigin {
|
|
||||||
r_factory: factory,
|
|
||||||
r_address: address,
|
|
||||||
r_resolver: resolver,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> {
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> {
|
||||||
fn as_ref(&self) -> &[u8] {
|
fn as_ref(&self) -> &[u8] {
|
||||||
&self.point
|
&self.point
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Addresses {
|
|
||||||
current: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Addresses {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start() -> Self {
|
|
||||||
Addresses { current: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory<F> {
|
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory<F> {
|
||||||
type Mtbl = Point<'a, Ctx, F::Mtbl>;
|
type Mtbl = Point<'a, Ctx, F::Mtbl>;
|
||||||
|
|
||||||
@ -226,8 +177,8 @@ impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFacto
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
let mut addresses = Addresses::start();
|
|
||||||
Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?)
|
Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,121 +187,6 @@ impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFacto
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResolverOrigin<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> {
|
|
||||||
r_factory: F,
|
|
||||||
r_address: Address,
|
|
||||||
r_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn _resolve_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
|
|
||||||
origin: Rc<ResolverOrigin<'a, Ctx, A::Fctr>>,
|
|
||||||
) -> Resolution<'a, Ctx, A> {
|
|
||||||
let resolution = origin.r_resolver.clone().resolve(origin.r_address);
|
|
||||||
Ctx::T::fmap(
|
|
||||||
move |resolved| match resolved {
|
|
||||||
Ok((src, resolver)) => match origin.r_factory.parse_slice(&src, resolver) {
|
|
||||||
Ok(mentionable) => Ok(Rc::new(mentionable)),
|
|
||||||
Err(parse_error) => Err(ResolutionError::Parse(parse_error)),
|
|
||||||
},
|
|
||||||
Err(lookup_error) => Err(ResolutionError::Lookup(lookup_error)),
|
|
||||||
},
|
|
||||||
resolution,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrigin<'a, Ctx, F> {
|
|
||||||
type Mtbl = F::Mtbl;
|
|
||||||
|
|
||||||
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
|
|
||||||
self.r_factory.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
|
|
||||||
_resolve_origin(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SliceDeserializer<'a> {
|
|
||||||
slice: &'a [u8],
|
|
||||||
pos: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a [u8]> for SliceDeserializer<'a> {
|
|
||||||
fn from(value: &'a [u8]) -> Self {
|
|
||||||
SliceDeserializer {
|
|
||||||
slice: value,
|
|
||||||
pos: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Deserializer for SliceDeserializer<'a> {
|
|
||||||
fn read_n(&mut self, n: usize) -> &[u8] {
|
|
||||||
let (left, right) = self.slice.split_at(min(n, self.slice.len()));
|
|
||||||
self.slice = right;
|
|
||||||
self.pos += left.len();
|
|
||||||
left
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_all(&mut self) -> &[u8] {
|
|
||||||
let left = self.slice;
|
|
||||||
self.slice = &[];
|
|
||||||
self.pos += left.len();
|
|
||||||
left
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tell(&self) -> usize {
|
|
||||||
self.pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)?;
|
|
||||||
let tail = deserializer.read_all();
|
|
||||||
if tail.is_empty() {
|
|
||||||
Ok(mentionable)
|
|
||||||
} else {
|
|
||||||
Err(factory.unexpected_tail(tail))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ExtFactory<'a, Ctx: 'a + Context>: Factory<'a, Ctx> {
|
|
||||||
fn parse_slice(
|
|
||||||
&self,
|
|
||||||
slice: &[u8],
|
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
|
||||||
) -> ParseResult<'a, Ctx, Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ExtDeserializer {
|
|
||||||
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: ?Sized + Deserializer> ExtDeserializer for D {
|
|
||||||
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]> {
|
|
||||||
let slice = self.read_n(N);
|
|
||||||
match slice.try_into() {
|
|
||||||
Ok(array) => Ok(array),
|
|
||||||
Err(_) => Err(slice),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Address {
|
impl Display for Address {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.write_fmt(format_args!("{}@{}", hex::encode(self.point), self.index))
|
f.write_fmt(format_args!("{}@{}", hex::encode(self.point), self.index))
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
//! Provides [Atomic]-[Mentionable] interface.
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// Generic implementation of a [Mentionable] for [Atomic]s.
|
||||||
pub struct AtomicObject<A: Atomic> {
|
pub struct AtomicObject<A: Atomic> {
|
||||||
atomic: A,
|
atomic: A,
|
||||||
}
|
}
|
||||||
@ -46,12 +49,14 @@ impl<'a, Ctx: 'a + Context, A: Atomic> Mentionable<'a, Ctx> for AtomicObject<A>
|
|||||||
fn points(&self, _points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {}
|
fn points(&self, _points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic implementation of a factory for [Atomic]s.
|
/// Generic implementation of a [Factory] for [Atomic]s.
|
||||||
pub struct AtomicFactory<A: Atomic>(PhantomData<A>);
|
pub struct AtomicFactory<A: Atomic> {
|
||||||
|
_pd: PhantomData<A>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<A: Atomic> AtomicFactory<A> {
|
impl<A: Atomic> AtomicFactory<A> {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
AtomicFactory(PhantomData)
|
AtomicFactory { _pd: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +75,7 @@ impl<'a, Ctx: 'a + Context, A: Atomic> Factory<'a, Ctx> for AtomicFactory<A> {
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
_resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
_addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
Ok(A::deserialize(deserializer)?.into())
|
Ok(A::deserialize(deserializer)?.into())
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! [`Pair`] implementation based on [`StaticPair`].
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ impl<A: Serializable, B: Serializable> StaticPairSerializable for Pair<A, B> {
|
|||||||
type SA = A;
|
type SA = A;
|
||||||
type SB = B;
|
type SB = B;
|
||||||
|
|
||||||
fn s_elements(&self) -> (&Self::SA, &Self::SB) {
|
fn elements(&self) -> (&Self::SA, &Self::SB) {
|
||||||
(&self.a, &self.b)
|
(&self.a, &self.b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,8 +91,4 @@ where
|
|||||||
b: self.b.factory(),
|
b: self.b.factory(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn elements(&self) -> (&Self::A, &Self::B) {
|
|
||||||
(&self.a, &self.b)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -88,16 +88,23 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Factory<'a, Ctx>
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
let rest =
|
let rest = match NullableFactory::new(self.clone()).deserialize(
|
||||||
match NullableFactory::new(self.clone()).deserialize(deserializer, resolver.clone()) {
|
deserializer,
|
||||||
Ok(rest) => rest,
|
resolver.clone(),
|
||||||
Err(ppe) => {
|
addresses,
|
||||||
return Err(StackParseError::Point(ppe));
|
) {
|
||||||
}
|
Ok(rest) => rest,
|
||||||
};
|
Err(ppe) => {
|
||||||
|
return Err(StackParseError::Point(ppe));
|
||||||
|
}
|
||||||
|
};
|
||||||
let element = Rc::new(
|
let element = Rc::new(
|
||||||
match self.element_factory.deserialize(deserializer, resolver) {
|
match self
|
||||||
|
.element_factory
|
||||||
|
.deserialize(deserializer, resolver, addresses)
|
||||||
|
{
|
||||||
Ok(element) => element,
|
Ok(element) => element,
|
||||||
Err(epe) => {
|
Err(epe) => {
|
||||||
return Err(StackParseError::Element(epe));
|
return Err(StackParseError::Element(epe));
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! Traits to better express parsing semantics.
|
||||||
|
|
||||||
pub mod static_pair;
|
pub mod static_pair;
|
||||||
|
|
||||||
use super::atomic::atomic_object::*;
|
use super::atomic::atomic_object::*;
|
||||||
@ -5,28 +7,44 @@ use super::atomic::*;
|
|||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
use crate::std::*;
|
use crate::std::*;
|
||||||
|
|
||||||
|
/// This factory should return an error on EOF.
|
||||||
pub trait InlineableFactory {}
|
pub trait InlineableFactory {}
|
||||||
|
|
||||||
|
/// This factory always reads the same amount of bytes or returns error.
|
||||||
pub trait FixedSizeFactory: InlineableFactory {
|
pub trait FixedSizeFactory: InlineableFactory {
|
||||||
|
/// For [`ConstSizeFactory`] this must return [`ConstSizeFactory::SIZE`].
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile-time analogue of [`FixedSizeFactory`].
|
||||||
pub trait ConstSizeFactory: FixedSizeFactory {
|
pub trait ConstSizeFactory: FixedSizeFactory {
|
||||||
|
/// Must be equal to [`FixedSizeFactory::size()`].
|
||||||
const SIZE: usize;
|
const SIZE: usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Object analogue of [`InlineableFactory`].
|
||||||
pub trait InlineableObject<'a, Ctx: 'a + Context>: 'a {}
|
pub trait InlineableObject<'a, Ctx: 'a + Context>: 'a {}
|
||||||
|
|
||||||
|
/// Object analogue of [`FixedSizeFactory`].
|
||||||
pub trait FixedSizeObject<'a, Ctx: 'a + Context>: InlineableObject<'a, Ctx> {
|
pub trait FixedSizeObject<'a, Ctx: 'a + Context>: InlineableObject<'a, Ctx> {
|
||||||
|
/// For [`ConstSizeObject`] this must return [`ConstSizeObject::SIZE`].
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Object analogue of [`ConstSizeFactory`].
|
||||||
pub trait ConstSizeObject<'a, Ctx: 'a + Context>: FixedSizeObject<'a, Ctx> {
|
pub trait ConstSizeObject<'a, Ctx: 'a + Context>: FixedSizeObject<'a, Ctx> {
|
||||||
|
/// Must be equal to [`FixedSizeObject::size()`].
|
||||||
const SIZE: usize;
|
const SIZE: usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Atomic analogue of [`InlineableFactory`]/[`InlineableObject`].
|
||||||
pub trait InlineableAtomic {}
|
pub trait InlineableAtomic {}
|
||||||
|
|
||||||
|
/// Atomic analogue of [`ConstSizeFactory`]/[`ConstSizeObject`].
|
||||||
|
///
|
||||||
|
/// Note: `FixedSizeAtomic` doesn't exist because it would
|
||||||
|
/// either be const anyway
|
||||||
|
/// or have a very undesireable implementation.
|
||||||
pub trait ConstSizeAtomic: InlineableAtomic {
|
pub trait ConstSizeAtomic: InlineableAtomic {
|
||||||
const SIZE: usize;
|
const SIZE: usize;
|
||||||
}
|
}
|
||||||
@ -64,6 +82,7 @@ where
|
|||||||
const SIZE: usize = A::Fctr::SIZE;
|
const SIZE: usize = A::Fctr::SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error returned by [`CheckedParse::deserialize_checked`]/[`CheckedSerialize::serialize_checked`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SizeError {
|
pub struct SizeError {
|
||||||
expected: usize,
|
expected: usize,
|
||||||
@ -81,6 +100,7 @@ impl Display for SizeError {
|
|||||||
|
|
||||||
impl Error for SizeError {}
|
impl Error for SizeError {}
|
||||||
|
|
||||||
|
/// Wrapper for [`SizeError`]/[`Factory::ParseError`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CheckedParseError<P: Error> {
|
pub enum CheckedParseError<P: Error> {
|
||||||
Parse(P),
|
Parse(P),
|
||||||
@ -104,18 +124,24 @@ impl<P: Error> From<P> for CheckedParseError<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returned by [`CheckedParse::deserialize_checked`].
|
||||||
pub type CheckedParseResult<'a, Ctx, F> =
|
pub type CheckedParseResult<'a, Ctx, F> =
|
||||||
Result<<F as Factory<'a, Ctx>>::Mtbl, CheckedParseError<<F as Factory<'a, Ctx>>::ParseError>>;
|
Result<<F as Factory<'a, Ctx>>::Mtbl, CheckedParseError<<F as Factory<'a, Ctx>>::ParseError>>;
|
||||||
|
|
||||||
|
/// Extension trait for factories that ensures fixed size read.
|
||||||
pub trait CheckedParse<'a, Ctx: 'a + Context>: FixedSizeFactory + Factory<'a, Ctx> {
|
pub trait CheckedParse<'a, Ctx: 'a + Context>: FixedSizeFactory + Factory<'a, Ctx> {
|
||||||
|
/// Verify proper read length using [`Deserializer::tell`].
|
||||||
fn deserialize_checked(
|
fn deserialize_checked(
|
||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> CheckedParseResult<'a, Ctx, Self>;
|
) -> CheckedParseResult<'a, Ctx, Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension trait for factories that ensures fixed size write.
|
||||||
pub trait CheckedSerialize<'a, Ctx: 'a + Context>: Serializable + FixedSizeObject<'a, Ctx> {
|
pub trait CheckedSerialize<'a, Ctx: 'a + Context>: Serializable + FixedSizeObject<'a, Ctx> {
|
||||||
|
/// Verify proper write length using [`Serializer::tell`].
|
||||||
fn serialize_checked(&self, serializer: &mut dyn Serializer) -> Result<(), SizeError>;
|
fn serialize_checked(&self, serializer: &mut dyn Serializer) -> Result<(), SizeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,10 +150,11 @@ impl<'a, Ctx: 'a + Context, F: FixedSizeFactory + Factory<'a, Ctx>> CheckedParse
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> CheckedParseResult<'a, Ctx, Self> {
|
) -> CheckedParseResult<'a, Ctx, Self> {
|
||||||
let expected_size = self.size();
|
let expected_size = self.size();
|
||||||
let start = deserializer.tell();
|
let start = deserializer.tell();
|
||||||
let result = self.deserialize(deserializer, resolver)?;
|
let result = self.deserialize(deserializer, resolver, addresses)?;
|
||||||
let end = deserializer.tell();
|
let end = deserializer.tell();
|
||||||
let received_size = end - start;
|
let received_size = end - start;
|
||||||
if received_size == expected_size {
|
if received_size == expected_size {
|
||||||
@ -161,6 +188,9 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx> + FixedSizeObject<'a, Ctx>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait useful for objects which aren't influenced by
|
||||||
|
/// whether some other type (for example, a generic parameter type)
|
||||||
|
/// is fixed-size or not.
|
||||||
pub trait AlwaysFixedSize {
|
pub trait AlwaysFixedSize {
|
||||||
fn _size(&self) -> usize;
|
fn _size(&self) -> usize;
|
||||||
}
|
}
|
||||||
@ -173,6 +203,7 @@ impl<F: AlwaysFixedSize> FixedSizeFactory for F {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile-time analogue of [`AlwaysFixedSize`].
|
||||||
pub trait AlwaysConstSize {
|
pub trait AlwaysConstSize {
|
||||||
const _SIZE: usize;
|
const _SIZE: usize;
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,66 @@
|
|||||||
|
//! Generic implementation for objects that are structured
|
||||||
|
//! like a pair of two other objects.
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
|
|
||||||
|
/// Trait to represent serialisation of object's data.
|
||||||
|
/// Due to serialisation being [Context]-free in RADN,
|
||||||
|
/// this functionality is in a separate trait.
|
||||||
pub trait StaticPairSerializable {
|
pub trait StaticPairSerializable {
|
||||||
|
/// First element's type. Must equal [`StaticPair::A`].
|
||||||
type SA: Serializable;
|
type SA: Serializable;
|
||||||
|
/// Second element's type. Must equal [`StaticPair::B`].
|
||||||
type SB: Serializable;
|
type SB: Serializable;
|
||||||
|
|
||||||
fn s_elements(&self) -> (&Self::SA, &Self::SB);
|
/// Borrow both elements.
|
||||||
|
fn elements(&self) -> (&Self::SA, &Self::SB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to be implemented on object data.
|
||||||
|
///
|
||||||
|
/// [`StaticPair::FA`]/[`StaticPair::FB`] are required members
|
||||||
|
/// for clarity and [`StaticPair`]'s simpler implementation
|
||||||
|
/// at the cost of having to specify two extra fields.
|
||||||
|
///
|
||||||
|
/// Note: [`StaticPair::FA`] requires [`InlineableFactory`] be implemented.
|
||||||
pub trait StaticPair<'a, Ctx: 'a + Context>:
|
pub trait StaticPair<'a, Ctx: 'a + Context>:
|
||||||
'a + StaticPairSerializable<SA = Self::A, SB = Self::B>
|
'a + StaticPairSerializable<SA = Self::A, SB = Self::B>
|
||||||
{
|
{
|
||||||
|
/// [Factory] data. May, depending on the usecase, include factory (factories) on the element(s).
|
||||||
type FactoryData: 'a + Clone;
|
type FactoryData: 'a + Clone;
|
||||||
|
/// First element's type. Must equal [`StaticPairSerializable::SA`].
|
||||||
type A: Mentionable<'a, Ctx, Fctr = Self::FA>;
|
type A: Mentionable<'a, Ctx, Fctr = Self::FA>;
|
||||||
|
/// Second element's type. Must equal [`StaticPairSerializable::SB`].
|
||||||
type B: Mentionable<'a, Ctx, Fctr = Self::FB>;
|
type B: Mentionable<'a, Ctx, Fctr = Self::FB>;
|
||||||
|
/// First element's factory.
|
||||||
type FA: Factory<'a, Ctx, Mtbl = Self::A> + InlineableFactory;
|
type FA: Factory<'a, Ctx, Mtbl = Self::A> + InlineableFactory;
|
||||||
|
/// Second element's factory.
|
||||||
type FB: Factory<'a, Ctx, Mtbl = Self::B>;
|
type FB: Factory<'a, Ctx, Mtbl = Self::B>;
|
||||||
|
/// See [Factory::ParseError].
|
||||||
type ParseError: 'a + Error;
|
type ParseError: 'a + Error;
|
||||||
|
|
||||||
|
/// Borrow both elements' factories.
|
||||||
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB);
|
fn factories(factory_data: &Self::FactoryData) -> (&Self::FA, &Self::FB);
|
||||||
|
/// Construct the object from the elements.
|
||||||
fn from_parsed(factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self;
|
fn from_parsed(factory_data: &Self::FactoryData, a: Self::A, b: Self::B) -> Self;
|
||||||
|
/// Regularise the error returned while parsing the first element.
|
||||||
fn from_error_a(
|
fn from_error_a(
|
||||||
factory_data: &Self::FactoryData,
|
factory_data: &Self::FactoryData,
|
||||||
error: <Self::FA as Factory<'a, Ctx>>::ParseError,
|
error: <Self::FA as Factory<'a, Ctx>>::ParseError,
|
||||||
) -> Self::ParseError;
|
) -> Self::ParseError;
|
||||||
|
/// Regularise the error returned while parsing the second element.
|
||||||
fn from_error_b(
|
fn from_error_b(
|
||||||
factory_data: &Self::FactoryData,
|
factory_data: &Self::FactoryData,
|
||||||
error: <Self::FB as Factory<'a, Ctx>>::ParseError,
|
error: <Self::FB as Factory<'a, Ctx>>::ParseError,
|
||||||
) -> Self::ParseError;
|
) -> Self::ParseError;
|
||||||
|
/// Derive factory data from the object data.
|
||||||
fn factory_data(&self) -> Self::FactoryData;
|
fn factory_data(&self) -> Self::FactoryData;
|
||||||
fn elements(&self) -> (&Self::A, &Self::B);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic implementation of a [Mentionable] for [StaticPair]s.
|
||||||
pub struct StaticPairObject<SP> {
|
pub struct StaticPairObject<SP> {
|
||||||
pair: SP,
|
pair: SP,
|
||||||
}
|
}
|
||||||
@ -58,13 +85,14 @@ impl<SP> Deref for StaticPairObject<SP> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic implementation of a [Factory] for [StaticPair]s.
|
||||||
pub struct StaticPairFactory<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> {
|
pub struct StaticPairFactory<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> {
|
||||||
factory_data: SP::FactoryData,
|
factory_data: SP::FactoryData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SP: StaticPairSerializable> Serializable for StaticPairObject<SP> {
|
impl<SP: StaticPairSerializable> Serializable for StaticPairObject<SP> {
|
||||||
fn serialize(&self, serializer: &mut dyn Serializer) {
|
fn serialize(&self, serializer: &mut dyn Serializer) {
|
||||||
let (a, b) = self.pair.s_elements();
|
let (a, b) = self.pair.elements();
|
||||||
a.serialize(serializer);
|
a.serialize(serializer);
|
||||||
b.serialize(serializer);
|
b.serialize(serializer);
|
||||||
}
|
}
|
||||||
@ -105,13 +133,14 @@ impl<'a, Ctx: 'a + Context, SP: StaticPair<'a, Ctx>> Factory<'a, Ctx>
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
let (fa, fb) = SP::factories(&self.factory_data);
|
let (fa, fb) = SP::factories(&self.factory_data);
|
||||||
let a: SP::A = match fa.deserialize(deserializer, resolver.clone()) {
|
let a: SP::A = match fa.deserialize(deserializer, resolver.clone(), addresses) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(error) => return Err(SP::from_error_a(&self.factory_data, error)),
|
Err(error) => return Err(SP::from_error_a(&self.factory_data, error)),
|
||||||
};
|
};
|
||||||
let b: SP::B = match fb.deserialize(deserializer, resolver) {
|
let b: SP::B = match fb.deserialize(deserializer, resolver, addresses) {
|
||||||
Ok(b) => b,
|
Ok(b) => b,
|
||||||
Err(error) => return Err(SP::from_error_b(&self.factory_data, error)),
|
Err(error) => return Err(SP::from_error_b(&self.factory_data, error)),
|
||||||
};
|
};
|
||||||
|
@ -67,8 +67,8 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Factory<'a, Ctx>
|
|||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn Deserializer,
|
deserializer: &mut dyn Deserializer,
|
||||||
resolver: std::rc::Rc<dyn Resolver<'a, Ctx>>,
|
resolver: std::rc::Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
addresses: &mut Addresses,
|
||||||
) -> ParseResult<'a, Ctx, Self> {
|
) -> ParseResult<'a, Ctx, Self> {
|
||||||
let mut addresses = Addresses::start();
|
|
||||||
let factory = self.factory.clone();
|
let factory = self.factory.clone();
|
||||||
let address = addresses.next(deserializer)?;
|
let address = addresses.next(deserializer)?;
|
||||||
Ok(if address.point == HASH_ZEROS {
|
Ok(if address.point == HASH_ZEROS {
|
||||||
|
Loading…
Reference in New Issue
Block a user