//! [`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> = ();
}