Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs91
1 files changed, 88 insertions, 3 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b56d371..d1264e0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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!()
+ }
+ }
+ };
+ };
+}