Point::cast
This commit is contained in:
parent
eb153d6396
commit
e40ea67e21
18
src/std.rs
18
src/std.rs
@ -15,6 +15,16 @@ struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
|
|||||||
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
|
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn wrapped_origin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>>(
|
||||||
|
factory: A::Fctr,
|
||||||
|
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
|
||||||
|
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
|
||||||
|
Rc::new(WrappedOrigin {
|
||||||
|
w_factory: factory,
|
||||||
|
w_resolve: Box::new(resolve),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
|
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
|
||||||
fn map<B: Mentionable<'a, Ctx>>(
|
fn map<B: Mentionable<'a, Ctx>>(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
@ -152,7 +162,11 @@ impl From<&[u8]> for PointParseError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
|
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
|
||||||
fn from_point(address: Address, factory: A::Fctr, resolver: Rc<dyn Resolver<'a, Ctx>>) -> Self {
|
fn from_address(
|
||||||
|
address: Address,
|
||||||
|
factory: A::Fctr,
|
||||||
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
|
) -> Self {
|
||||||
Point {
|
Point {
|
||||||
point: address.point,
|
point: address.point,
|
||||||
origin: Rc::new(ResolverOrigin {
|
origin: Rc::new(ResolverOrigin {
|
||||||
@ -191,7 +205,7 @@ impl Addresses {
|
|||||||
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
resolver: Rc<dyn Resolver<'a, Ctx>>,
|
||||||
factory: A::Fctr,
|
factory: A::Fctr,
|
||||||
) -> Result<Point<'a, Ctx, A>, &'b [u8]> {
|
) -> Result<Point<'a, Ctx, A>, &'b [u8]> {
|
||||||
Ok(Point::from_point(
|
Ok(Point::from_address(
|
||||||
self.next(deserializer)?,
|
self.next(deserializer)?,
|
||||||
factory,
|
factory,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -79,8 +79,11 @@ fn _parse_slice<A: Atomic>(slice: &[u8]) -> Result<A, A::ParseError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension trait to provide method-like utilities associated with [Atomic]s.
|
||||||
pub trait ExtAtomic: Atomic {
|
pub trait ExtAtomic: Atomic {
|
||||||
|
/// Short-hand for getting specific [`AtomicFactory`].
|
||||||
fn f() -> AtomicFactory<Self>;
|
fn f() -> AtomicFactory<Self>;
|
||||||
|
/// Static equivalent of [`ExtFactory::parse_slice`].
|
||||||
fn parse_slice(slice: &[u8]) -> Result<Self, Self::ParseError>;
|
fn parse_slice(slice: &[u8]) -> Result<Self, Self::ParseError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
|
//! [`Plain`] type for storing raw byte sequnces.
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::std::atomic::*;
|
use crate::std::atomic::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
/// Raw bytes storage. Use [`Plain::raw`] to get the data.
|
||||||
|
///
|
||||||
|
/// Note: this type uses [`Deserializer::read_all`] for parsing.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct Plain {
|
pub struct Plain {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This shouldn't happen given [`Deserializer::read_all`] being used for parsing.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum PlainParseError {}
|
pub enum PlainParseError {}
|
||||||
|
|
||||||
@ -40,9 +46,15 @@ impl Atomic for Plain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Plain {
|
impl Plain {
|
||||||
|
/// Copy bytes into a new instance.
|
||||||
pub fn from_slice(slice: &[u8]) -> Self {
|
pub fn from_slice(slice: &[u8]) -> Self {
|
||||||
Plain { data: slice.into() }
|
Plain { data: slice.into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copy of bytes stored inside.
|
||||||
|
pub fn raw(&self) -> Vec<u8> {
|
||||||
|
self.data.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
//! Utilities to convert from typeless instances defined in [`crate::core`].
|
||||||
|
//! See [`TypelessMentionable::cast`]/[`Point::cast`].
|
||||||
|
//!
|
||||||
|
//! p.s. the implementation is horrific.
|
||||||
|
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
use crate::std::*;
|
use crate::std::*;
|
||||||
|
|
||||||
@ -5,13 +10,22 @@ struct CastResolver<'a, Ctx: 'a + Context> {
|
|||||||
points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
|
points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used to represent errors that might arise during resolution/parsion.
|
||||||
|
/// Is expected to be classified as [`Context::LookupError`] rather than [`Factory::ParseError`].
|
||||||
|
/// [`CastError::AddressIndexOutOfBounds`] and [`CastError::AddressPointMismatch`]
|
||||||
|
/// variants generally shouldn't happen.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CastError<'a> {
|
pub enum CastError<'a> {
|
||||||
Typeless(TypelessError<'a>),
|
Typeless(TypelessError<'a>),
|
||||||
|
/// If you don't know what that means, it's a good idea to [`panic!`].
|
||||||
|
/// Happens due to internal resolver using indices rather than `point`s.
|
||||||
|
/// This error usually indicates inconsistent behaviour
|
||||||
|
/// of [`Mentionable::points`] and/or [`Mentionable::topology`].
|
||||||
AddressIndexOutOfBounds {
|
AddressIndexOutOfBounds {
|
||||||
index: usize,
|
index: usize,
|
||||||
length: usize,
|
length: usize,
|
||||||
},
|
},
|
||||||
|
/// See [`CastError::AddressIndexOutOfBounds`].
|
||||||
AddressPointMismatch {
|
AddressPointMismatch {
|
||||||
expected: Hash,
|
expected: Hash,
|
||||||
received: Hash,
|
received: Hash,
|
||||||
@ -84,12 +98,15 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returned by [`TypelessMentionable::cast`].
|
||||||
pub type CastResult<'a, Ctx, A> =
|
pub type CastResult<'a, Ctx, A> =
|
||||||
Result<A, <<A as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError>;
|
Result<A, <<A as Mentionable<'a, Ctx>>::Fctr as Factory<'a, Ctx>>::ParseError>;
|
||||||
|
|
||||||
impl<'a, Ctx: Context> TypelessMentionable<'a, Ctx>
|
impl<'a, Ctx: Context> TypelessMentionable<'a, Ctx>
|
||||||
where
|
where
|
||||||
Ctx::LookupError<'a>: From<CastError<'a>>,
|
Ctx::LookupError<'a>: From<CastError<'a>>,
|
||||||
{
|
{
|
||||||
|
/// Re-parse the object as if it is of a specific type. Has potential to break topology.
|
||||||
pub fn cast<A: Mentionable<'a, Ctx>>(&self, factory: A::Fctr) -> CastResult<'a, Ctx, A> {
|
pub fn cast<A: Mentionable<'a, Ctx>>(&self, factory: A::Fctr) -> CastResult<'a, Ctx, A> {
|
||||||
factory.parse_slice(
|
factory.parse_slice(
|
||||||
&self.bytes(),
|
&self.bytes(),
|
||||||
@ -99,3 +116,35 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context> Point<'a, Ctx, TypelessMentionable<'a, Ctx>>
|
||||||
|
where
|
||||||
|
Ctx::LookupError<'a>: From<CastError<'a>>,
|
||||||
|
{
|
||||||
|
/// See [`TypelessMentionable::cast`]
|
||||||
|
pub fn cast<A: Mentionable<'a, Ctx>>(&self, factory: A::Fctr) -> Point<'a, Ctx, A> {
|
||||||
|
let typeless_origin = self.origin.clone();
|
||||||
|
let origin: Rc<dyn Origin<Ctx, Mtbl = A>> = wrapped_origin(factory.clone(), move || {
|
||||||
|
let factory = factory.clone();
|
||||||
|
Ctx::T::fmap(
|
||||||
|
move |resolved| match resolved {
|
||||||
|
Ok(typeless_mentionable) => match typeless_mentionable.cast(factory) {
|
||||||
|
Ok(mentionable) => Ok(Rc::new(mentionable)),
|
||||||
|
Err(parse_error) => Err(ResolutionError::Parse(parse_error)),
|
||||||
|
},
|
||||||
|
Err(error) => Err(ResolutionError::Lookup(match error {
|
||||||
|
ResolutionError::Lookup(lookup_error) => lookup_error,
|
||||||
|
ResolutionError::Parse(parse_error) => {
|
||||||
|
CastError::Typeless(parse_error).into()
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
typeless_origin.clone().resolve(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
Point {
|
||||||
|
point: self.point,
|
||||||
|
origin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -71,7 +71,7 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Factory<'a, Ctx>
|
|||||||
Ok(if address.point == HASH_ZEROS {
|
Ok(if address.point == HASH_ZEROS {
|
||||||
Nullable::Null(factory)
|
Nullable::Null(factory)
|
||||||
} else {
|
} else {
|
||||||
Nullable::NotNull(Point::from_point(address, factory, resolver))
|
Nullable::NotNull(Point::from_address(address, factory, resolver))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user