fatality_proc_macro/
lib.rs

1#![deny(clippy::dbg_macro)]
2#![deny(unused_crate_dependencies)]
3
4use proc_macro2::{Span, TokenStream};
5use syn::spanned::Spanned;
6
7mod types;
8
9pub(crate) use self::types::*;
10
11fn fatality2_inner(
12    attr: proc_macro2::TokenStream,
13    input: proc_macro2::TokenStream,
14) -> syn::Result<proc_macro2::TokenStream> {
15    let bail_if_has_generics = |generics: &syn::Generics, span: Span| -> syn::Result<()> {
16        if !generics.params.is_empty() {
17            return Err(syn::Error::new(
18                span,
19                "Generics  `enum`-types are currently supported",
20            ));
21        }
22        Ok(())
23    };
24    let attr = syn::parse2::<Attr>(attr)?;
25    match syn::parse2::<syn::Item>(input.clone())? {
26        syn::Item::Enum(item) => {
27            bail_if_has_generics(&item.generics, item.span())?;
28            fatality_enum_gen(attr, item)
29        }
30        syn::Item::Struct(item) => {
31            bail_if_has_generics(&item.generics, item.span())?;
32            fatality_struct_gen(attr, item)
33        }
34        other => Err(syn::Error::new(
35            other.span(),
36            "Only `enum` and `struct` types are supported",
37        )),
38    }
39}
40
41fn fatality2(
42    attr: proc_macro2::TokenStream,
43    input: proc_macro2::TokenStream,
44) -> proc_macro2::TokenStream {
45    let orig = input.clone();
46    let ts = fatality2_inner(attr, input).unwrap_or_else(|e| -> proc_macro2::TokenStream {
47        let mut ts = proc_macro2::TokenStream::new();
48        ts.extend(orig);
49        ts.extend(e.to_compile_error());
50        ts
51    });
52
53    expander::Expander::new("fatality")
54        .add_comment("Generated by `#[fatality::fatality]`".to_owned())
55        // .fmt(expander::Edition::_2021)
56        .dry(!cfg!(feature = "expand"))
57        .write_to_out_dir(ts)
58        .unwrap()
59}
60
61#[proc_macro_attribute]
62pub fn fatality(
63    attr: proc_macro::TokenStream,
64    input: proc_macro::TokenStream,
65) -> proc_macro::TokenStream {
66    let attr = TokenStream::from(attr);
67    let input = TokenStream::from(input);
68
69    let output: TokenStream = fatality2(attr, input);
70
71    proc_macro::TokenStream::from(output)
72}
73
74#[cfg(test)]
75mod tests;