Impl IntoIterator

This commit is contained in:
dalance 2019-07-12 01:31:15 +09:00
parent 6bdbad0f0a
commit 69e6c35103
4 changed files with 128 additions and 20 deletions

View File

@ -21,7 +21,7 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream {
for v in &data.variants { for v in &data.variants {
let ident = &v.ident; let ident = &v.ident;
let item = quote! { let item = quote! {
#name::#ident(x) => { let ret: AnyNode<'a> = x.into(); vec![ret] }, #name::#ident(x) => { x.into() },
}; };
items = quote! { items = quote! {
#items #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! { quote! {
vec![] vec![].into()
} }
} }
}; };
@ -48,14 +74,14 @@ fn impl_node(ast: &syn::DeriveInput) -> TokenStream {
format!("{}", stringify!(#name)) format!("{}", stringify!(#name))
} }
fn next(&'a self) -> Vec<AnyNode<'a>> { fn next(&'a self) -> AnyNodes<'a> {
#next #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 { 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>; type IntoIter = Iter<'a>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
let node: AnyNode<'a> = self.into(); let nodes: AnyNodes<'a> = self.into();
Iter { next: vec![node] } Iter { next: nodes }
} }
} }
}; };
@ -99,7 +125,7 @@ fn impl_any_node(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident; let name = &ast.ident;
let gen = quote! { let gen = quote! {
impl<'a> #name<'a> { impl<'a> #name<'a> {
fn next(&self) -> Vec<AnyNode<'a>> { fn next(&self) -> AnyNodes<'a> {
match self { match self {
#items #items
} }

View File

@ -1,27 +1,109 @@
use crate::ast::*; use crate::ast::*;
use crate::parser::*; use crate::parser::*;
impl<'a> From<&'a Span<'a>> for AnyNode<'a> { include!(concat!(env!("OUT_DIR"), "/any_node.rs"));
fn from(x: &'a Span<'a>) -> Self {
AnyNode::Span(x) pub struct AnyNodes<'a>(pub Vec<AnyNode<'a>>);
impl<'a> From<Vec<AnyNode<'a>>> for AnyNodes<'a> {
fn from(x: Vec<AnyNode<'a>>) -> 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<T>> for AnyNodes<'a>
where
&'a T: Into<AnyNodes<'a>>,
{
fn from(x: &'a Vec<T>) -> 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<T>> for AnyNodes<'a>
where
&'a T: Into<AnyNodes<'a>>,
{
fn from(x: &'a Option<T>) -> 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<AnyNodes<'a>>,
&'a U: Into<AnyNodes<'a>>,
{
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<AnyNodes<'a>>,
&'a U: Into<AnyNodes<'a>>,
&'a V: Into<AnyNodes<'a>>,
{
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<AnyNodes<'a>>,
&'a U: Into<AnyNodes<'a>>,
&'a V: Into<AnyNodes<'a>>,
&'a W: Into<AnyNodes<'a>>,
{
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 struct Iter<'a> {
pub next: Vec<AnyNode<'a>>, pub next: AnyNodes<'a>,
} }
impl<'a> Iterator for Iter<'a> { impl<'a> Iterator for Iter<'a> {
type Item = AnyNode<'a>; type Item = AnyNode<'a>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let ret = self.next.pop(); let ret = self.next.0.pop();
if let Some(x) = ret.clone() { if let Some(x) = ret.clone() {
let mut x = x.next(); let mut x = x.next();
x.reverse(); x.0.reverse();
self.next.append(&mut x); self.next.0.append(&mut x.0);
} }
ret ret
} }

View File

@ -3,14 +3,14 @@ use crate::parser::*;
pub trait Node<'a> { pub trait Node<'a> {
fn test(&'a self) -> String; fn test(&'a self) -> String;
fn next(&'a self) -> Vec<AnyNode<'a>>; fn next(&'a self) -> AnyNodes<'a>;
} }
impl<'a> Node<'a> for Span<'a> { impl<'a> Node<'a> for Span<'a> {
fn test(&'a self) -> String { fn test(&'a self) -> String {
String::from("") String::from("")
} }
fn next(&'a self) -> Vec<AnyNode<'a>> { fn next(&'a self) -> AnyNodes<'a> {
vec![] vec![].into()
} }
} }

View File

@ -551,7 +551,7 @@ mod tests {
#[test] #[test]
fn test_node() { 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"); //assert_eq!(x.test(), "aaaa");
//let y: AnyNode = (&x).into(); //let y: AnyNode = (&x).into();
for a in &x { for a in &x {