trapeze-macros 0.2.0

Macros for trapeze
Documentation
use std::path::PathBuf;

use proc_macro::TokenStream;
use proc_macro2::Span;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{bracketed, parse_quote, Error, LitStr, Result, Token};

struct BracketedList {
    values: Punctuated<LitStr, Token![,]>,
}

impl BracketedList {
    fn to_vec(&self) -> Vec<PathBuf> {
        self.values
            .iter()
            .map(|f| PathBuf::from(f.value()))
            .collect()
    }
}

impl Parse for BracketedList {
    fn parse(input: ParseStream) -> Result<Self> {
        let content;
        let _ = bracketed!(content in input);
        Ok(BracketedList {
            values: Punctuated::<LitStr, Token![,]>::parse_terminated(&content)?,
        })
    }
}

pub struct Input {
    pub files: Vec<PathBuf>,
    pub includes: Vec<PathBuf>,
    pub span: Span,
}

pub fn parse_input(input: TokenStream) -> Result<Input> {
    let input: proc_macro2::TokenStream = input.into();
    let span = input.span();
    let files: Punctuated<BracketedList, Token![,]> = parse_quote! { #input };
    let lists: Vec<_> = files.iter().collect();
    let (files, includes) = match lists.as_slice() {
        [files] => {
            let files = files.to_vec();
            let includes = files
                .iter()
                .map(|p| p.parent().unwrap().to_owned())
                .collect();
            (files.to_vec(), includes)
        }
        [files, includes] => (files.to_vec(), includes.to_vec()),
        [] => {
            return Err(Error::new(
                input.span(),
                "Expected a list of files to compile",
            ));
        }
        _ => {
            return Err(Error::new(
                input.span(),
                "Expected a list of files to compile",
            ));
        }
    };
    Ok(Input {
        files,
        includes,
        span,
    })
}