Diffstat (limited to 'src/protocol/visitor/value.rs')
-rw-r--r--src/protocol/visitor/value.rs83
1 files changed, 48 insertions, 35 deletions
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 1ed5682..ca5d046 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -3,21 +3,21 @@
//! In some sense, this is the most basic protocol.
use crate::{
- any::{TypeName, TypeNameable},
+ any::{MaybeSized, TypeName},
+ bijective_higher_ranked_type,
effect::{Effect, Future},
higher_ranked_type,
hkt::AnySend,
- nameable,
protocol::{walker::hint::HintMeta, Visitor},
Flow,
};
-use super::Status;
+use super::{recoverable::Recoverable, Status};
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'ctx, T, E: Effect<'ctx>> {
+pub trait Value<'ctx, T: MaybeSized::Trait<'ctx>, E: Effect<'ctx>> {
/// Visit a value of type `T`.
///
/// Use this to give a value to a visitor. Its expected that a walker
@@ -27,22 +27,27 @@ pub trait Value<'ctx, T, E: Effect<'ctx>> {
/// If a [`ControlFlow::Break`] is returned then the walker
/// should stop walking as soon as possible as there has likely been
/// and error.
- fn visit<'a>(&'a mut self, value: T) -> Future<'a, 'ctx, Flow, E>;
+ fn visit<'a>(&'a mut self, value: MaybeSized::T<'a, 'ctx, T>) -> Future<'a, 'ctx, Flow, E>;
}
-pub type DynValue<'a, 'ctx, T, E> = dyn Value<'ctx, T, E> + Send + 'a;
-
-nameable! {
- pub struct Name['ctx, T, E] for<'a>;
-
- impl [T::Name, E] for DynValue<'a, 'ctx, T, E> where {
- T: TypeNameable<'ctx> + ?Sized,
+bijective_higher_ranked_type! {
+ pub type DynValue['ctx][T, E][]: MaybeSized['ctx][]
+ for<'a>
+ (dyn Value<'ctx, T, E> + Send + 'a)
+ where {
E: Effect<'ctx>,
+ T: ?Sized + MaybeSized::Trait<'ctx> + 'ctx
}
+}
- impl [T, E] where DynValue<'a, 'ctx, T::Nameable, E> {
- T: TypeName<'ctx> + ?Sized,
+bijective_higher_ranked_type! {
+ pub type [][E][T[][]]: TypeName[][]
+ for<'ctx>
+ (DynValue<'ctx, TypeName::T<'ctx, T>, E>)
+ (DynValue<'ctx, T, E>)
+ where {
E: Effect<'ctx>,
+ T: ?Sized,
}
}
@@ -51,17 +56,22 @@ higher_ranked_type! {
}
// This enrolls the Value protocol into the walker hint system.
-impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'a, 'ctx, T, E> {
+impl<'a, 'ctx: 'a, T, E: Effect<'ctx>> HintMeta<'ctx> for DynValue<'ctx, T, E> {
type Known = ValueKnownHkt<'ctx>;
type Hint = ();
}
-pub fn visit_value<'a, 'ctx, T: TypeNameable<'ctx>, E: Effect<'ctx>>(
+pub fn visit_value<'a, 'ctx, T: MaybeSized::Member<'a, 'ctx> + 'ctx, E: Effect<'ctx>>(
visitor: Visitor<'a, 'ctx>,
value: T,
-) -> Future<'a, 'ctx, Status, E> {
- if let Some(object) = visitor.upcast_mut::<DynValue<'_, 'ctx, T, E>>() {
+) -> Future<'a, 'ctx, Status, E>
+where
+ MaybeSized::HigherRanked<'a, 'ctx, T>: TypeName::Member<'ctx> + Sized,
+{
+ if let Some(object) =
+ visitor.upcast_mut::<DynValue<'ctx, MaybeSized::HigherRanked<'a, 'ctx, T>, E>>()
+ {
// Allow the visitor to give a hint if it wants.
E::map(object.visit(value), |flow| match flow {
Flow::Continue => {
@@ -83,11 +93,14 @@ pub fn visit_value<'a, 'ctx, T: TypeNameable<'ctx>, E: Effect<'ctx>>(
#[cfg(test)]
mod test {
- use core::{marker::PhantomData, ops::ControlFlow};
+ use core::marker::PhantomData;
use crate::{
any::{
- static_wrapper::{BorrowedMutStatic, BorrowedStatic, OwnedStatic},
+ static_wrapper::{
+ BorrowedMutStatic, BorrowedStatic, DynBorrowedMutStatic, DynBorrowedStatic,
+ DynOwnedStatic, OwnedStatic,
+ },
AnyTrait,
},
any_trait,
@@ -100,7 +113,7 @@ mod test {
fn visit() {
struct Visitor<E>(Option<i32>, PhantomData<fn() -> E>);
- impl<'ctx, E> Value<'ctx, OwnedStatic<i32>, E> for Visitor<E>
+ impl<'ctx, E> Value<'ctx, DynOwnedStatic<'ctx, i32>, E> for Visitor<E>
where
E: Effect<'ctx>,
{
@@ -115,7 +128,7 @@ mod test {
}
}
- impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, i32>, E> for Visitor<E>
+ impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, i32>, E> for Visitor<E>
where
E: Effect<'ctx>,
{
@@ -131,9 +144,9 @@ mod test {
}
any_trait! {
- impl['a, 'ctx, E] Visitor<E> = [
- DynValue<'a, 'ctx, OwnedStatic<i32>, E>,
- DynValue<'a, 'ctx, BorrowedStatic<'ctx, i32>, E>,
+ impl['ctx, E] Visitor<E> = [
+ DynValue<'ctx, DynOwnedStatic<'ctx, i32>, E>,
+ DynValue<'ctx, DynBorrowedStatic<'ctx, i32>, E>,
] where E: Effect<'ctx>,
}
@@ -141,7 +154,7 @@ mod test {
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
Spin::block_on(
object
- .upcast_mut::<DynValue<'_, '_, OwnedStatic<i32>, Blocking>>()
+ .upcast_mut::<DynValue<'_, DynOwnedStatic<'_, i32>, Blocking>>()
.unwrap()
.visit(OwnedStatic(42)),
);
@@ -151,7 +164,7 @@ mod test {
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
Spin::block_on(
object
- .upcast_mut::<DynValue<'_, '_, BorrowedStatic<'_, i32>, Blocking>>()
+ .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, i32>, Blocking>>()
.unwrap()
.visit(BorrowedStatic(&101)),
);
@@ -163,7 +176,7 @@ mod test {
fn visit_borrowed() {
struct Visitor<'ctx, E>(Option<&'ctx mut String>, PhantomData<fn() -> E>);
- impl<'ctx, E> Value<'ctx, BorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
+ impl<'ctx, E> Value<'ctx, DynBorrowedMutStatic<'ctx, String>, E> for Visitor<'ctx, E>
where
E: Effect<'ctx>,
{
@@ -180,8 +193,8 @@ mod test {
}
any_trait! {
- impl['a, 'ctx, E] Visitor<'ctx, E> = [
- DynValue<'a, 'ctx, BorrowedMutStatic<'ctx, String>, E>,
+ impl['ctx, E] Visitor<'ctx, E> = [
+ DynValue<'ctx, DynBorrowedMutStatic<'ctx, String>, E>,
] where E: Effect<'ctx>
}
@@ -191,7 +204,7 @@ mod test {
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
Spin::block_on(
object
- .upcast_mut::<DynValue<'_, '_, _, Blocking>>()
+ .upcast_mut::<DynValue<'_, DynBorrowedMutStatic<'_, _>, Blocking>>()
.unwrap()
.visit(BorrowedMutStatic(&mut y)),
);
@@ -204,7 +217,7 @@ mod test {
fn visit_borrowed_unsized() {
struct Visitor<'ctx, E>(Option<&'ctx str>, PhantomData<fn() -> E>);
- impl<'ctx, E> Value<'ctx, BorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
+ impl<'ctx, E> Value<'ctx, DynBorrowedStatic<'ctx, str>, E> for Visitor<'ctx, E>
where
E: Effect<'ctx>,
{
@@ -220,8 +233,8 @@ mod test {
}
any_trait! {
- impl['a, 'ctx, E] Visitor<'ctx, E> = [
- DynValue<'a, 'ctx, BorrowedStatic<'ctx, str>, E>,
+ impl['ctx, E] Visitor<'ctx, E> = [
+ DynValue<'ctx, DynBorrowedStatic<'ctx, str>, E>,
] where E: Effect<'ctx>
}
@@ -231,7 +244,7 @@ mod test {
let object: &mut (dyn AnyTrait<'_> + Send) = &mut v;
Spin::block_on(
object
- .upcast_mut::<DynValue<'_, '_, BorrowedStatic<'_, str>, Blocking>>()
+ .upcast_mut::<DynValue<'_, DynBorrowedStatic<'_, str>, Blocking>>()
.unwrap()
.visit(BorrowedStatic(&y)),
);