fatality_proc_macro/
lib.rs1#![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 .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;