1extern crate proc_macro;
2
3use proc_macro2::TokenStream;
4use std::convert::TryFrom;
5use syn::DeriveInput;
6
7mod ast;
8mod precond;
9mod unit;
10
11#[proc_macro_derive(UnitVal, attributes(unitval))]
12pub fn unitval_derive(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
13 let tokens = syn::parse2(tokens.into()).unwrap();
14 expand_unitval(tokens).unwrap_or_else(|e| e).into()
15}
16
17fn expand_unitval(input: DeriveInput) -> Result<TokenStream, TokenStream> {
18 let enum_data = precond::unit_enum(&input.data)?;
19 let tokens = unit::Tokens::try_from(enum_data)?;
20
21 let mut ast = ast::impl_as_unit_val(&input, &tokens);
22 ast.extend(ast::impl_from_unit_val(&input, &tokens));
23 Ok(ast)
24}