Diffstat (limited to 'src/builtins/visitor/value.rs')
| -rw-r--r-- | src/builtins/visitor/value.rs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/builtins/visitor/value.rs b/src/builtins/visitor/value.rs new file mode 100644 index 0000000..6a1b450 --- /dev/null +++ b/src/builtins/visitor/value.rs @@ -0,0 +1,41 @@ +//! [`Protocol`] for giving a visitor an owned value. +//! +//! In some sense, this is the most basic protocol. + +use core::{marker::PhantomData, ops::ControlFlow}; + +use crate::{builtins::walker::hint::Meta, protocol::Protocol}; + +/// [`Protocol`] for giving a visitor an owned value. +/// +/// A value of type `T` can be given to the visitor using +/// [`Object::visit()`]. There is a restriction that `T: 'static`. +pub struct Value<T>(PhantomData<fn() -> T>); + +/// Trait object for the [`Value`] protocol. +/// +/// Types implementing the [`Value`] protocol will implement this trait. +pub trait Object<'ctx, T> { + /// Visit a value of type `T`. + /// + /// Use this to give a value to a visitor. Its expected that a walker + /// only calls this once per usage of the trait object, but that is not + /// forced. + /// + /// 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(&mut self, value: T) -> ControlFlow<()>; +} + +// This is what makes Value a protocol. +impl<T: 'static> Protocol for Value<T> { + type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx, T>; +} + +// This enrolls the Value protocol into the walker hint system. +impl<T: 'static> Meta for Value<T> { + type Known<'a, 'ctx: 'a> = (); + + type Hint<'a, 'ctx: 'a> = (); +} |