Diffstat (limited to 'src/builtins/visitor/value.rs')
-rw-r--r--src/builtins/visitor/value.rs41
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> = ();
+}