xmlity-derive 0.0.9

Derive proc-macros for xmlity.
Documentation
pub enum DeriveError {
    Darling(darling::Error),
    Custom {
        message: String,
        span: proc_macro2::Span,
    },
}

pub type DeriveResult<T> = Result<T, DeriveError>;

impl From<darling::Error> for DeriveError {
    fn from(e: darling::Error) -> Self {
        DeriveError::Darling(e)
    }
}

impl From<syn::Error> for DeriveError {
    fn from(e: syn::Error) -> Self {
        DeriveError::Darling(e.into())
    }
}

impl DeriveError {
    pub fn into_compile_error(self) -> proc_macro2::TokenStream {
        match self {
            DeriveError::Darling(e) => e.write_errors(),
            DeriveError::Custom { message, span } => {
                syn::Error::new(span, message).to_compile_error()
            }
        }
    }

    pub fn custom<T: Into<String>>(error: T) -> Self {
        Self::custom_with_span(error, proc_macro2::Span::call_site())
    }

    pub fn custom_with_span<T: Into<String>, S: Into<proc_macro2::Span>>(
        error: T,
        span: S,
    ) -> Self {
        Self::Custom {
            message: error.into(),
            span: span.into(),
        }
    }
}

pub trait DeriveMacro {
    fn input_to_derive(ast: &syn::DeriveInput) -> Result<proc_macro2::TokenStream, DeriveError>
    where
        Self: Sized;
}

pub trait DeriveMacroExt {
    fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream;
}

impl<T: DeriveMacro> DeriveMacroExt for T {
    fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
        let ast = syn::parse_macro_input!(input as syn::DeriveInput);
        T::input_to_derive(&ast)
            .unwrap_or_else(|e| e.into_compile_error())
            .into()
    }
}