Diffstat (limited to 'src/build/protocols.rs')
| -rw-r--r-- | src/build/protocols.rs | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/src/build/protocols.rs b/src/build/protocols.rs new file mode 100644 index 0000000..30dc074 --- /dev/null +++ b/src/build/protocols.rs @@ -0,0 +1,289 @@ +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; + } +} |