orion-error-derive 0.8.0

Derive macros for orion-error
Documentation
fn impl_display(input: DeriveInput) -> Result<TokenStream2> {
    let ident = input.ident;
    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

    match input.data {
        Data::Enum(data) => {
            let arms = data
                .variants
                .iter()
                .map(|variant| {
                    let args = OrionAttrs::from_attrs(&variant.attrs)?;
                    if args.transparent {
                        let (pattern, inner) = transparent_variant_pattern(variant)?;
                        Ok(quote! {
                            #pattern => ::std::fmt::Display::fmt(#inner, f)
                        })
                    } else if let Some(message) = args.display_message() {
                        let pattern = variant_pattern(variant);
                        Ok(quote! {
                            #pattern => f.write_str(#message)
                        })
                    } else {
                        Err(Error::new(
                            variant.span(),
                            "missing #[orion_error(message = ...)] or string literal #[orion_error(identity = ...)]",
                        ))
                    }
                })
                .collect::<Result<Vec<_>>>()?;

            Ok(quote! {
                impl #impl_generics ::std::fmt::Display for #ident #ty_generics #where_clause {
                    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                        match self {
                            #(#arms,)*
                        }
                    }
                }
            })
        }
        Data::Struct(data) => {
            let args = OrionAttrs::from_attrs(&input.attrs)?;
            let body = if args.transparent {
                let inner = transparent_struct_binding(&data.fields)?;
                let pattern = struct_pattern(&ident, &data.fields);
                quote! {
                    match self {
                        #pattern => ::std::fmt::Display::fmt(#inner, f),
                    }
                }
            } else if let Some(message) = args.display_message() {
                quote! { f.write_str(#message) }
            } else {
                return Err(Error::new(
                    ident.span(),
                    "missing container #[orion_error(message = ...)] or string literal #[orion_error(identity = ...)]",
                ));
            };

            Ok(quote! {
                impl #impl_generics ::std::fmt::Display for #ident #ty_generics #where_clause {
                    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                        #body
                    }
                }
            })
        }
        Data::Union(_) => Err(Error::new(
            ident.span(),
            "OrionError can only be derived for enums or structs",
        )),
    }
}