use proc_macro2::{TokenStream as TokenStream2, TokenTree};
use quote::ToTokens;
use syn::{
parse::{Parse, ParseStream},
punctuated::Punctuated,
Token,
};
#[derive(Debug, Clone)]
pub struct PipeOperator();
impl Parse for PipeOperator {
fn parse(input: ParseStream) -> syn::Result<Self> {
_ = input.parse::<Token![|]>()?;
_ = input.parse::<Token![>]>()?;
Ok(PipeOperator {})
}
}
#[derive(Debug, Clone)]
pub struct PipeLine {
pub expressions: Vec<TokenStream2>,
}
impl Parse for PipeLine {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut expressions: Vec<TokenStream2> = vec![];
'expressions_loop: while !input.is_empty() {
let mut parts = vec![];
'parts_loop: while !input.is_empty() {
if input.peek(Token![,]) {
expressions.push(TokenStream2::from_iter(parts));
break 'expressions_loop;
}
if input.peek(Token![|]) && input.peek2(Token![>]) {
_ = input.parse::<PipeOperator>()?;
break 'parts_loop;
}
let part = input.parse::<TokenTree>()?;
parts.push(part.to_token_stream());
}
expressions.push(TokenStream2::from_iter(parts));
}
Ok(PipeLine { expressions })
}
}
#[derive(Debug, Clone)]
pub struct PipeStatement {
pub lines: Vec<PipeLine>,
}
impl Parse for PipeStatement {
fn parse(input: ParseStream) -> syn::Result<Self> {
let punctuated_lines =
Punctuated::<PipeLine, Token![,]>::parse_terminated(input)?;
let mut lines = vec![];
for op in punctuated_lines {
lines.push(op);
}
Ok(PipeStatement { lines })
}
}