enum_conversion_derive/
lib.rs1mod impls;
2mod parse_attributes;
3mod parse_enum;
4mod templates;
5
6extern crate proc_macro;
7
8use std::collections::HashMap;
9
10use proc_macro::TokenStream;
11use quote::ToTokens;
12use syn::DeriveInput;
13use tera::{Context, Tera};
14
15use crate::parse_attributes::{parse_custom_error_config, ErrorConfig};
16
17const ENUM_CONV_LIFETIME: &str = "'enum_conv";
18
19use crate::parse_enum::{
20 create_marker_enums, fetch_fields_from_enum, fetch_impl_generics,
21 fetch_name_with_generic_params, get_marker,
22};
23
24#[proc_macro_attribute]
25#[allow(non_snake_case)]
26pub fn EnumConversions(args: TokenStream, input: TokenStream) -> TokenStream {
27 let error_config = parse_custom_error_config(args.into());
28 let enum_ast = syn::parse(input).unwrap();
29
30 impl_conversions(error_config, enum_ast)
31}
32
33#[proc_macro_attribute]
34#[allow(non_snake_case)]
35pub fn DeriveTryFrom(_: TokenStream, input: TokenStream) -> TokenStream {
36 input
37}
38
39fn impl_conversions(error_config: ErrorConfig, mut ast: DeriveInput) -> TokenStream {
41 let tera = templates::templater();
42 let name = &ast.ident.to_string();
43 let (fullname, lifetimes) = fetch_name_with_generic_params(&ast);
44 let impl_generics = fetch_impl_generics(&ast, ENUM_CONV_LIFETIME, &lifetimes);
45
46 let field_map = fetch_fields_from_enum(&mut ast);
47 let mut tokens: TokenStream = ast.to_token_stream().to_string().parse().unwrap();
48
49 tokens.extend::<TokenStream>(create_marker_enums(name, &field_map).parse().unwrap());
50 tokens.extend::<TokenStream>(
51 impls::impl_get_variant(name, &fullname, &impl_generics, &field_map, &tera)
52 .parse()
53 .unwrap(),
54 );
55 tokens.extend::<TokenStream>(
56 impls::impl_try_from(
57 name,
58 &fullname,
59 &impl_generics,
60 &error_config,
61 &field_map,
62 &tera,
63 )
64 .parse()
65 .unwrap(),
66 );
67 tokens.extend::<TokenStream>(
68 impls::impl_try_to(
69 name,
70 &fullname,
71 &impl_generics,
72 &error_config,
73 &field_map,
74 &tera,
75 )
76 .parse()
77 .unwrap(),
78 );
79 tokens.extend::<TokenStream>(
80 impls::impl_from(&fullname, &impl_generics, &field_map, &tera)
81 .parse()
82 .unwrap(),
83 );
84 tokens
85}