fpr-cli-derives 0.4.7

A library that allows one to write cli tools quickly. (derive macros)
Documentation
use darling::FromVariant;
use syn::LitInt;

use super::prelude::*;

#[derive(Debug, FromDeriveInput)]
#[darling(attributes(), supports(enum_unit))]
struct Actions {
    ident: Ident,
    data: ast::Data<Opt, ()>,
}

#[derive(Debug, FromVariant)]
#[darling(attributes())]
struct Opt {
    ident: Ident,
}

fn a(p: Actions) -> Result<TokenStream, String> {
    let i = &p.ident;

    let f: Vec<_> = p.data.take_enum().ok_or(format!("Expected an enum."))?;

    let names_base: Vec<_> = f
        .iter()
        .map(|e| {
            let k = LitStr::new(e.ident.to_string().to_case(Case::Snake).as_str(), i.span());
            let x = &e.ident;
            (k, x)
        })
        .collect();
    let names: Vec<_> = names_base
        .iter()
        .map(|(k, x)| {
            quote! { #i::#x => #k }
        })
        .collect();
    let str_names: Vec<_> = names_base
        .iter()
        .map(|(k, _)| {
            quote! { #k }
        })
        .collect();
    let str2names: Vec<_> = names_base
        .iter()
        .map(|(k, x)| {
            quote! { #k -> #i::#x }
        })
        .collect();

    let c = LitInt::new(format!("{}", names.len()).as_str(), i.span());

    let names2: Vec<_> = f
        .iter()
        .map(|e| {
            let x = &e.ident;
            quote! { #i::#x }
        })
        .collect();

    Ok(quote! {
        impl Actions for #i {
            fn get(prompt: &str, starting_input: Option<&str>) -> Result<Self, MyErr>{
                const V: [#i; #c] = [ #( #names2, )* ];
                Ok(V[select_line(prompt, &V, |e| [e.to_string()]).with_starting_filter_input(starting_input.unwrap_or("")).prompt()?.index].to_owned())
            }
            fn list() -> &'static [&'static str] {
                const V: [&str; #c] = [ #( #str_names, )* ];
                &V
            }
            fn parse(s: &str) -> Option<Self> {
                match s {
                    #( #str2names, )*
                    _ => None,
                }
            }
        }
        impl ToString for #i {
            fn to_string(&self) -> String {
                format!("{}", match &self {
                    #( #names, )*
                })
            }
        }
    }
    .into())
}

pub fn f(i: TokenStream) -> TokenStream {
    let p = match Actions::from_derive_input(&parse_macro_input!(i as DeriveInput)) {
        Ok(p) => p,
        Err(e) => return e.write_errors().into(),
    };

    match a(p) {
        Ok(p) => p,
        Err(e) => Error::custom(e).write_errors().into(),
    }
}