pub mod hint {
use crate::protocol::{Implementer, Protocol};
/// Protocol for requesting a visitor give a hint.
///
/// This protocol is implemented by visitors.
///
/// Some walkers don't know what the data they are walking actually represents.
/// This protocol allows such walkers to request the visitor to give a hint of what
/// it is expecting.
///
/// This can also be paired with the [`Recoverable`][super::recoverable::Recoverable]
/// protocol to place the walker in a recoverable mode for the visitor to try multiple
/// protocols.
pub enum RequestHint {}
/// Object implementing the [`RequestHint`] protocol.
pub trait RequestHintObject<'ctx> {
/// Call this to request a hint.
///
/// `hints` is expected to be the walker. This is what the visitor (`Self`)
/// will call to give a hint using the [`Hint`] protocol.
///
/// `needs_hints` can be `false` if the walker can continue without a hint.
fn request_hint(&mut self, hints: &mut dyn Implementer<'ctx>) -> Result<(), ()>;
}
impl Protocol for RequestHint {
type Object<'a, 'ctx: 'a> = &'a mut dyn RequestHintObject<'ctx>;
}
}
pub mod recoverable {
use crate::{
protocol::{Implementer, Protocol},
walk::protocols::hint::Meta,
};
/// Protocol for providing a recoverable walker.
///
/// This protocol is implemented by visitors.
pub enum Recoverable {}
/// Implemented by walkers that can be reset.
pub trait RecoverableWalker<'ctx> {
/// Start a new walk with the walker reset to it's starting state.
fn new_walk(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<(), ()>;
}
/// Object implementing the [`Recoverable`] protocol.
pub trait Object<'ctx> {
/// Visit with a recoverable walker.
///
/// The visitor can then use the `walker` to try multiple different ways
/// of walking.
fn visit(&mut self, walker: &mut dyn RecoverableWalker<'ctx>) -> Result<(), ()>;
}
impl Protocol for Recoverable {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx>;
}
impl Meta for Recoverable {
type Known<'a, 'ctx: 'a> = ();
type Hint<'a, 'ctx: 'a> = ();
}
}
pub mod owned {
use core::marker::PhantomData;
use crate::{protocol::Protocol, walk::protocols::hint::Meta};
pub struct Owned<T: 'static>(PhantomData<fn() -> T>);
pub trait Object<'ctx, T: 'static> {
fn visit(&mut self, value: T) -> Result<(), ()>;
}
impl<T: 'static> Protocol for Owned<T> {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx, T>;
}
impl<T: 'static> Meta for Owned<T> {
type Known<'a, 'ctx: 'a> = ();
type Hint<'a, 'ctx: 'a> = ();
}
}
pub mod borrowed {
use core::marker::PhantomData;
use crate::{protocol::Protocol, walk::protocols::hint::Meta};
pub struct Borrowed<T: 'static>(PhantomData<fn() -> T>);
pub enum Value<'a, 'ctx, T: 'static> {
Temp(&'a T),
Context(&'ctx T),
Static(&'static T),
}
pub trait Object<'ctx, T: 'static> {
fn visit(&mut self, value: Value<'_, 'ctx, T>) -> Result<(), ()>;
}
impl<T: 'static> Protocol for Borrowed<T> {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx, T>;
}
pub enum Kind {
Temp,
Context,
Static,
}
pub struct Known {
pub kind: Option<Kind>,
}
pub struct Hint {
pub kind: Option<Kind>,
}
impl<T: 'static> Meta for Borrowed<T> {
type Known<'a, 'ctx: 'a> = Known;
type Hint<'a, 'ctx: 'a> = Hint;
}
}
pub mod borrowed_mut {
use core::marker::PhantomData;
use crate::{protocol::Protocol, walk::protocols::hint::Meta};
pub struct BorrowedMut<T: 'static>(PhantomData<fn() -> T>);
pub enum Value<'a, 'ctx, T: 'static> {
Temp(&'a mut T),
Context(&'ctx mut T),
Static(&'static mut T),
}
pub trait Object<'ctx, T: 'static> {
fn visit(&mut self, value: Value<'_, 'ctx, T>) -> Result<(), ()>;
}
impl<T: 'static> Protocol for BorrowedMut<T> {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx, T>;
}
pub enum Kind {
Temp,
Context,
Static,
}
pub struct Known {
pub kind: Option<Kind>,
}
pub struct Hint {
pub kind: Option<Kind>,
}
impl<T: 'static> Meta for BorrowedMut<T> {
type Known<'a, 'ctx: 'a> = Known;
type Hint<'a, 'ctx: 'a> = Hint;
}
}
pub mod tagged {
use crate::{
protocol::{Implementer, Protocol},
walk::protocols::hint::Meta,
};
pub enum Tagged {}
pub trait TaggedWalker<'ctx> {
fn walk_tag(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<(), ()>;
fn walk_value(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<(), ()>;
}
pub trait Object<'ctx> {
fn visit(&mut self, walker: &mut dyn TaggedWalker<'ctx>) -> Result<(), ()>;
}
impl Protocol for Tagged {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx>;
}
impl Meta for Tagged {
type Known<'a, 'ctx: 'a> = ();
type Hint<'a, 'ctx: 'a> = ();
}
}
pub mod sequence {
use crate::{
protocol::{Implementer, Protocol},
walk::protocols::hint::Meta,
};
pub enum Sequence {}
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
pub enum Status {
Done,
Continue,
}
pub trait SequenceWalker<'ctx> {
fn next(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<Status, ()>;
}
pub trait Object<'ctx> {
fn visit(&mut self, walker: &mut dyn SequenceWalker<'ctx>) -> Result<(), ()>;
}
impl Protocol for Sequence {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx>;
}
#[derive(Default)]
pub struct Known {
pub len: (usize, Option<usize>),
}
pub struct Hint {
pub len: (usize, Option<usize>),
}
impl Meta for Sequence {
type Known<'a, 'ctx: 'a> = Known;
type Hint<'a, 'ctx: 'a> = Hint;
}
}
pub mod map {
use crate::{
protocol::{Implementer, Protocol},
walk::protocols::hint::Meta,
};
pub enum Map {}
#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Debug)]
pub enum Status {
Done,
Continue,
}
pub trait MapWalker<'ctx> {
fn next_key(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<Status, ()>;
fn value(&mut self, visitor: &mut dyn Implementer<'ctx>) -> Result<(), ()>;
}
pub trait Object<'ctx> {
fn visit(&mut self, walker: &mut dyn MapWalker<'ctx>) -> Result<(), ()>;
}
impl Protocol for Map {
type Object<'a, 'ctx: 'a> = &'a mut dyn Object<'ctx>;
}
#[derive(Default)]
pub struct Known {
pub len: (usize, Option<usize>),
}
pub struct Hint {
pub len: (usize, Option<usize>),
}
impl Meta for Map {
type Known<'a, 'ctx: 'a> = Known;
type Hint<'a, 'ctx: 'a> = Hint;
}
}