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 {
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<AnyNode<'a>> {
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<AnyNode<'a>> {
fn next(&self) -> AnyNodes<'a> {
match self {
#items
}

View File

@ -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<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 next: Vec<AnyNode<'a>>,
pub next: AnyNodes<'a>,
}
impl<'a> Iterator for Iter<'a> {
type Item = AnyNode<'a>;
fn next(&mut self) -> Option<Self::Item> {
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
}

View File

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

View File

@ -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 {