use effectful::bound::Dynamic; use effectful::effective::Effective; use effectful::environment::{Environment}; use effectful::effective::{Canonical}; use effectful::{DynBind, SendSync}; use crate::{ any::AnyTrait, any::{type_name, OwnedStatic}, hkt::Marker, protocol::{ visitor::{ request_hint, visit_value, EffectiveVisitExt as _, Value, ValueKnown, VisitResult, }, walker::hint::{DynVisitorWith, Hint}, DynVisitor, DynWalker, }, Walker, }; #[derive(SendSync)] pub struct IntegerWalker { value: Dynamic, _marker: Marker, } pub trait Integer: 'static + Copy + core::fmt::Debug + core::fmt::Display + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto { } fn try_into, U>(value: T) -> Option { value.try_into().ok() } impl IntegerWalker { pub fn new(value: T) -> Self { Self { value: Dynamic(value), _marker: Default::default(), } } } #[derive(SendSync)] pub struct IntegerWalkerError { value: Dynamic, } impl ::core::fmt::Debug for IntegerWalkerError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("IntegerWalkerError") .field("value", &self.value) .finish() } } impl ::core::fmt::Display for IntegerWalkerError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("IntegerWalkerError") .field("value", &self.value) .finish() } } impl<'ctx, T: Integer, E: Environment> Walker<'ctx, E> for IntegerWalker where Dynamic: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, { type Error = IntegerWalkerError; type Output = Dynamic; fn walk<'visitor: 'effect, 'lt: 'effect, 'effect>( self, visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, ) -> Canonical<'effect, Result, E> where Self: 'effect, { let value = self.value; E::value((self, visitor)) .update_map((), |_, (this, visitor)| { request_hint::(visitor.cast(), DynWalker(this)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() }) .map((), |_, ((_, visitor), result)| (visitor, result)) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, i8>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, u8>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, i16>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, u16>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, i32>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, u32>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, i64>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, u64>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, i128>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, u128>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, isize>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .cast::<()>() .if_skipped(value, |value, visitor| { if let Some(value) = try_into::<_, usize>(value.0) { visit_value::<_, E>(visitor.cast(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } }) .map(value, |value, (_, result)| match result { VisitResult::Skipped(()) => Err(IntegerWalkerError { value }), VisitResult::Control(_) => Ok(value), }) .cast() } } impl Integer for T where T: 'static + Copy + core::fmt::Debug + core::fmt::Display + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto + TryInto { } impl<'lt, 'ctx: 'lt, T, E> AnyTrait<'lt, 'ctx> for IntegerWalker where T: Integer, E: Environment, Dynamic: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, Dynamic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, for<'a> Dynamic<&'a OwnedStatic>: DynBind, { } // any_trait! { // impl['ctx, T][E] IntegerWalker = [ // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // HintProto, E>>, // ] where // } macro_rules! impl_hints { ($($type:ty),* $(,)?) => { $(impl<'ctx, T: Integer, E: Environment> Hint<'ctx, type_name::Raised<'static, 'ctx, dyn Value<'ctx, OwnedStatic<$type>, E>>> for IntegerWalker where Dynamic: DynBind, Dynamic>: DynBind, for<'a> Dynamic<&'a OwnedStatic<$type>>: DynBind { fn hint<'this: 'e, 'visitor: 'e, 'lt: 'e, 'hint: 'e, 'e>( &'this mut self, visitor: DynVisitorWith<'visitor, 'lt, 'ctx, type_name::Raised<'static, 'ctx, dyn Value<'ctx, OwnedStatic<$type>, E>>>, _hint: (), ) -> Canonical<'e, crate::protocol::visitor::VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { if let Some(value) = try_into::<_, $type>(self.value.0) { visit_value::<_, E>(visitor.into_inner(), OwnedStatic(value)) .map((), |_, x| VisitResult::unit_skipped(x)) .cast() } else { E::value(VisitResult::Skipped(())).cast() } } fn known<'a>( &'a mut self, _hint: &'a (), ) -> Canonical<'a, Result>, ()>, E> where ValueKnown<'a, OwnedStatic<$type>>: DynBind { E::value(Ok(ValueKnown { preview: None })).cast() } })* }; } impl_hints![u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize];