Diffstat (limited to 'src/build/protocols.rs')
-rw-r--r--src/build/protocols.rs289
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;
+ }
+}