diff --git a/node_derive/src/lib.rs b/node_derive/src/lib.rs index 61c1871..3d77f1a 100644 --- a/node_derive/src/lib.rs +++ b/node_derive/src/lib.rs @@ -21,7 +21,7 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream { for v in &data.variants { let ident = &v.ident; let item = quote! { - #name::#ident(x) => { let ret: AnyNode<'a> = x.into(); vec![ret] }, + #name::#ident(x) => { x.into() }, }; items = quote! { #items @@ -35,9 +35,35 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream { } } } + syn::Data::Struct(ref data) => { + let mut items = quote! {}; + if let syn::Fields::Named(f) = &data.fields { + for f in &f.named { + if let Some(ident) = &f.ident { + if ident.to_string() == "nodes" { + if let syn::Type::Tuple(t) = &f.ty { + for i in 0..t.elems.len() { + let i = syn::Index::from(i); + items = quote! { + #items + let mut nodes : AnyNodes = (&(self.nodes.#i)).into(); + ret.append(&mut nodes.0); + }; + } + } + } + } + } + } + quote! { + let mut ret = Vec::new(); + #items + ret.into() + } + } _ => { quote! { - vec![] + vec![].into() } } }; @@ -48,14 +74,14 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream { format!("{}", stringify!(#name)) } - fn next(&'a self) -> Vec> { + fn next(&'a self) -> AnyNodes<'a> { #next } } - impl<'a> From<&'a #name<'a>> for AnyNode<'a> { + impl<'a> From<&'a #name<'a>> for AnyNodes<'a> { fn from(x: &'a #name<'a>) -> Self { - AnyNode::#name(x) + vec![AnyNode::#name(x)].into() } } @@ -64,8 +90,8 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream { type IntoIter = Iter<'a>; fn into_iter(self) -> Self::IntoIter { - let node: AnyNode<'a> = self.into(); - Iter { next: vec![node] } + let nodes: AnyNodes<'a> = self.into(); + Iter { next: nodes } } } }; @@ -99,7 +125,7 @@ fn impl_any_node(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; let gen = quote! { impl<'a> #name<'a> { - fn next(&self) -> Vec> { + fn next(&self) -> AnyNodes<'a> { match self { #items } diff --git a/src/ast/any_node.rs b/src/ast/any_node.rs index dd7b29d..f11655e 100644 --- a/src/ast/any_node.rs +++ b/src/ast/any_node.rs @@ -1,27 +1,109 @@ use crate::ast::*; use crate::parser::*; -impl<'a> From<&'a Span<'a>> for AnyNode<'a> { - fn from(x: &'a Span<'a>) -> Self { - AnyNode::Span(x) +include!(concat!(env!("OUT_DIR"), "/any_node.rs")); + +pub struct AnyNodes<'a>(pub Vec>); + +impl<'a> From>> for AnyNodes<'a> { + fn from(x: Vec>) -> Self { + AnyNodes(x) } } -include!(concat!(env!("OUT_DIR"), "/any_node.rs")); +impl<'a> From<&'a Span<'a>> for AnyNodes<'a> { + fn from(x: &'a Span<'a>) -> Self { + vec![AnyNode::Span(x)].into() + } +} + +impl<'a, T: 'a> From<&'a Vec> for AnyNodes<'a> +where + &'a T: Into>, +{ + fn from(x: &'a Vec) -> Self { + let mut ret = Vec::new(); + for x in x { + ret.append(&mut x.into().0); + } + ret.into() + } +} + +impl<'a, T: 'a> From<&'a Option> for AnyNodes<'a> +where + &'a T: Into>, +{ + fn from(x: &'a Option) -> Self { + let mut ret = Vec::new(); + if let Some(x) = x { + ret.append(&mut x.into().0); + } + ret.into() + } +} + +impl<'a, T: 'a, U: 'a> From<&'a (T, U)> for AnyNodes<'a> +where + &'a T: Into>, + &'a U: Into>, +{ + fn from(x: &'a (T, U)) -> Self { + let mut ret = Vec::new(); + let (t, u) = x; + ret.append(&mut t.into().0); + ret.append(&mut u.into().0); + ret.into() + } +} + +impl<'a, T: 'a, U: 'a, V: 'a> From<&'a (T, U, V)> for AnyNodes<'a> +where + &'a T: Into>, + &'a U: Into>, + &'a V: Into>, +{ + fn from(x: &'a (T, U, V)) -> Self { + let mut ret = Vec::new(); + let (t, u, v) = x; + ret.append(&mut t.into().0); + ret.append(&mut u.into().0); + ret.append(&mut v.into().0); + ret.into() + } +} + +impl<'a, T: 'a, U: 'a, V: 'a, W: 'a> From<&'a (T, U, V, W)> for AnyNodes<'a> +where + &'a T: Into>, + &'a U: Into>, + &'a V: Into>, + &'a W: Into>, +{ + fn from(x: &'a (T, U, V, W)) -> Self { + let mut ret = Vec::new(); + let (t, u, v, w) = x; + ret.append(&mut t.into().0); + ret.append(&mut u.into().0); + ret.append(&mut v.into().0); + ret.append(&mut w.into().0); + ret.into() + } +} pub struct Iter<'a> { - pub next: Vec>, + pub next: AnyNodes<'a>, } impl<'a> Iterator for Iter<'a> { type Item = AnyNode<'a>; fn next(&mut self) -> Option { - let ret = self.next.pop(); + let ret = self.next.0.pop(); if let Some(x) = ret.clone() { let mut x = x.next(); - x.reverse(); - self.next.append(&mut x); + x.0.reverse(); + self.next.0.append(&mut x.0); } ret } diff --git a/src/ast/node.rs b/src/ast/node.rs index ef9f02e..b858ce0 100644 --- a/src/ast/node.rs +++ b/src/ast/node.rs @@ -3,14 +3,14 @@ use crate::parser::*; pub trait Node<'a> { fn test(&'a self) -> String; - fn next(&'a self) -> Vec>; + fn next(&'a self) -> AnyNodes<'a>; } impl<'a> Node<'a> for Span<'a> { fn test(&'a self) -> String { String::from("") } - fn next(&'a self) -> Vec> { - vec![] + fn next(&'a self) -> AnyNodes<'a> { + vec![].into() } } diff --git a/src/parser/expressions/numbers.rs b/src/parser/expressions/numbers.rs index e1b8712..fef8774 100644 --- a/src/parser/expressions/numbers.rs +++ b/src/parser/expressions/numbers.rs @@ -551,7 +551,7 @@ mod tests { #[test] fn test_node() { - if let Ok((_, x)) = all_consuming(number)(Span::new_extra("10", 0)) { + if let Ok((_, x)) = all_consuming(number)(Span::new_extra("10.00", 0)) { //assert_eq!(x.test(), "aaaa"); //let y: AnyNode = (&x).into(); for a in &x {