patum 0.1.6

Make enum conform to a given pattern
Documentation
use std::collections::{BTreeMap, BTreeSet};

use proc_macro2::{Ident};

use quote::ToTokens;
use syn::{
    parse::{Parse, ParseStream},
    token::{self},
    Fields,
    Token, WhereClause, punctuated::Punctuated, Variant, braced
};

pub type Shape = (Option<Ident>, Fields);
pub type TypeMap = BTreeMap<String, BTreeSet<String>>;

pub fn parse_fields(input: ParseStream) -> syn::Result<Shape> {
    if input.peek(Token![$]) {
        let _: Token![$] = input.parse()?;
    }
    Ok((
        input.parse()?,
        if input.peek(token::Brace) {
            Fields::Named(input.parse()?)
        } else if input.peek(token::Paren) {
            Fields::Unnamed(input.parse()?)
        } else {
            Fields::Unit
        },
    ))
}

pub fn parse_pattern(input: ParseStream) -> syn::Result<Vec<Shape>> {
    let mut pattern = vec![input.call(parse_fields)?];

    while input.peek(token::Or) {
        let _: token::Or = input.parse()?;
        pattern.push(input.call(parse_fields)?);
    }

    Ok(pattern)
}

pub fn parse_enum(
    input: ParseStream,
) -> syn::Result<(
    Option<WhereClause>,
    token::Brace,
    Punctuated<Variant, Token![,]>,
)> {
    let where_clause = input.parse()?;

    let content;
    let brace = braced!(content in input);
    let variants = content.parse_terminated(Variant::parse)?;

    Ok((where_clause, brace, variants))
}

pub fn string<T: ToTokens>(x: &T) -> String {
    x.to_token_stream().to_string()
}