Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 91 |
1 files changed, 88 insertions, 3 deletions
@@ -1,14 +1,15 @@ //! # Design //! -#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(all(not(test), not(feature = "std")), no_std)] #[cfg(feature = "alloc")] extern crate alloc; +mod build; pub mod protocol; -pub mod build; -pub mod walk; +pub mod symbol; +mod walk; // pub mod impls; // pub mod transform; @@ -18,3 +19,87 @@ pub mod walk; // // pub use walk::Walk; // pub use walk::Walker; + +pub use build::*; +pub use walk::*; + +#[macro_export] +macro_rules! Build { + { + $(#[$($attr:tt)*])* + $vis:vis struct $name:ident {$( + $field:ident: $type:ty + ),* $(,)?} + } => { + const _: () = { + impl<'ctx> $crate::Build<'ctx> for $name { + type Builder = StructBuilder; + } + + #[derive(Default)] + $vis struct StructBuilder {$( + $field: Option<$type> + ),*} + + impl<'ctx> $crate::Builder<'ctx> for StructBuilder { + type Error = (); + + type Value = $name; + + fn as_visitor(&mut self) -> &mut dyn $crate::protocol::Implementer<'ctx> { + self + } + + fn build(self) -> Result<Self::Value, Self::Error> { + if let StructBuilder {$($field: Some($field)),*} = self { + Ok($name {$($field),*}) + } else { + Err(()) + } + } + } + + $crate::protocol::implementer! { + impl['ctx] StructBuilder = [ + + ]; + } + + impl<'ctx> $crate::Walk<'ctx> for $name { + type Walker = StructWalker; + } + + $vis struct StructWalker { + value: Option<$name>, + hint_given: bool, + } + + impl From<$name> for StructWalker { + fn from(value: $name) -> Self { + Self { + value: Some(value), + hint_given: false + } + } + } + + impl<'ctx> $crate::Walker<'ctx> for StructWalker { + type Error = (); + + type Output = (); + + fn walk(&mut self, visitor: &mut dyn $crate::protocol::Implementer<'ctx>) -> Result<Self::Output, Self::Error> { + use $crate::protocol::ImplementerExt; + // Want kinds for tags. + if let Some(interface) = visitor.interface_for::<$crate::builtins::visitor::request_hint>() { + interface.as_object().visit(&mut self); + } + $( + <$type as $crate::Walk>::Walker::from(self.0.$field).walk(visitor); + )* + todo!() + } + } + }; + }; +} |