Origin::resolve_bytes

This commit is contained in:
AF 2023-06-30 20:19:16 +00:00
parent 7a88f17c36
commit b50d7582ba
7 changed files with 92 additions and 5 deletions

View File

@ -8,6 +8,7 @@ pub trait Origin<'a, Ctx: Context<'a>>: 'a {
fn factory(&self) -> OFctr<'a, Ctx, Self>;
/// Try resolving the value.
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl>;
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx>;
}
pub type OFctr<'a, Ctx, O> = Fctr<'a, Ctx, <O as Origin<'a, Ctx>>::Mtbl>;

View File

@ -50,4 +50,8 @@ impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Origin<'a, Ctx> for ResolverOrig
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
_resolve_origin(self)
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
self.r_resolver.clone().resolve(self.r_address)
}
}

View File

@ -8,6 +8,7 @@ pub mod inlining;
mod local_origin;
pub mod nullable;
pub mod point;
pub mod singular;
pub mod tracing;
pub mod typeless;
mod wrapped_origin;

View File

@ -201,9 +201,12 @@ fn cast_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
where
Ctx::LookupError: From<CastError<'a>>,
{
wrapped_origin(factory.clone(), move || {
cast_resolve(typeless_origin.clone(), factory.clone())
})
let origin_rb = typeless_origin.clone();
wrapped_origin(
factory.clone(),
move || cast_resolve(typeless_origin.clone(), factory.clone()),
move || origin_rb.clone().resolve_bytes(),
)
}
impl<'a, Ctx: Context<'a>> Point<'a, Ctx, TypelessMentionable<'a, Ctx>>

View File

@ -3,6 +3,9 @@ use std::rc::Rc;
use crate::func::context::*;
use crate::rcore::*;
use super::singular::*;
use super::*;
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
fn prepare_bytes_for_hashing(mentioned: &A) -> Vec<u8> {
let mut vec = mentioned.topology().to_vec();
@ -38,6 +41,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOri
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, Self::Mtbl> {
Ctx::pure(Ok(self.0.clone()))
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
Ctx::pure(Ok((
self.0.bytes(),
Rc::new(SingularResolver::from_mentionable(self.0.as_ref())),
)))
}
}
impl<A> From<Rc<A>> for LocalOrigin<A> {

59
src/rstd/singular.rs Normal file
View File

@ -0,0 +1,59 @@
use crate::rcore::*;
use crate::rstd::*;
pub trait SingularResolution<'a, Ctx: Context<'a>>: 'a {
fn singular(self: Rc<Self>) -> HashResolution<'a, Ctx>;
fn s_hash(&self) -> Hash;
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> SingularResolution<'a, Ctx>
for Point<'a, Ctx, A>
{
fn singular(self: Rc<Self>) -> HashResolution<'a, Ctx> {
self.origin.clone().resolve_bytes()
}
fn s_hash(&self) -> Hash {
self.point
}
}
pub struct SingularResolver<'a, Ctx: Context<'a>> {
points: Vec<Rc<dyn SingularResolution<'a, Ctx>>>,
}
impl<'a, Ctx: Context<'a>> SingularResolver<'a, Ctx> {
pub fn from_mentionable<A: Mentionable<'a, Ctx>>(a: &A) -> Self {
let mut points = Vec::new();
a.points_typed(&mut points);
Self { points }
}
}
impl<'a, Ctx: Context<'a>> Resolver<'a, Ctx> for SingularResolver<'a, Ctx> {
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, Ctx> {
let point = self.points.get(address.index).unwrap_or_else(|| {
panic!(
"singularity out-of-bounds: {}/{}.",
address.index,
self.points.len()
)
});
if point.s_hash() != address.point {
panic!(
"address mismatch at index {}: {}!={}",
address.index,
hex::encode(address.point),
hex::encode(point.s_hash()),
)
}
point.clone().singular()
}
}
impl<'a, Ctx: Context<'a>> TakesPoints<'a, Ctx> for Vec<Rc<dyn SingularResolution<'a, Ctx>>> {
fn take<A: Mentionable<'a, Ctx>>(&mut self, point: &Point<'a, Ctx, A>) {
self.push(Rc::new(point.clone()) as Rc<dyn SingularResolution<'a, Ctx>>);
}
}

View File

@ -5,10 +5,12 @@ use super::*;
pub fn wrapped_origin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>>(
factory: A::Fctr,
resolve: impl 'a + Fn() -> Resolution<'a, Ctx, A>,
resolve_bytes: impl 'a + Fn() -> HashResolution<'a, Ctx>,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = A>> {
Rc::new(WrappedOrigin {
w_factory: factory,
w_resolve: Box::new(resolve),
w_resolve_bytes: Box::new(resolve_bytes),
})
}
@ -23,15 +25,17 @@ pub trait MappableOrigin<'a, Ctx: Context<'a>>: Origin<'a, Ctx> {
+ Fn(ParseError<'a, Ctx, OFctr<'a, Ctx, Self>>) -> ParseError<'a, Ctx, B::Fctr>,
map_factory: impl 'a + FnOnce(OFctr<'a, Ctx, Self>) -> B::Fctr,
) -> Rc<dyn Origin<'a, Ctx, Mtbl = B>> {
let origin = self.clone();
let origin_r = self.clone();
let origin_rb = self.clone();
let origin: WrappedOrigin<'a, Ctx, B> = WrappedOrigin {
w_factory: map_factory(self.factory()),
w_resolve: Box::new(move || {
let origin = origin.clone();
let origin = origin_r.clone();
let map_ok = map_ok.clone();
let map_err = map_err.clone();
map_resolve(move || origin.clone().resolve(), map_ok, map_err)
}),
w_resolve_bytes: Box::new(move || origin_rb.clone().resolve_bytes()),
};
Rc::new(origin)
}
@ -53,6 +57,7 @@ fn map_resolve<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, B: Mentionable<'a,
struct WrappedOrigin<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> Resolution<'a, Ctx, A>>,
w_resolve_bytes: Box<dyn 'a + Fn() -> HashResolution<'a, Ctx>>,
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
@ -65,4 +70,8 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedO
fn resolve(self: Rc<Self>) -> Resolution<'a, Ctx, A> {
(self.w_resolve)()
}
fn resolve_bytes(self: Rc<Self>) -> HashResolution<'a, Ctx> {
(self.w_resolve_bytes)()
}
}