armour-derive 0.28.0

DDL and serialization for key-value storage
Documentation
#[macro_use]
extern crate darling;
extern crate proc_macro2;
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;

use darling::util::Flag;
use syn::{Data, DeriveInput, Expr, ExprPath, LitStr, parse_macro_input};

/// Adds metrics tracking to the function.
///
/// # Example
/// ```rust,ignore
/// #[armour_metrics(prefix = "my_prefix", name = tree.raw.name.clone())]
/// fn my_function() {
///     // function body
/// }
/// ```
#[proc_macro_attribute]
pub fn armour_metrics(attr: TokenStream, item: TokenStream) -> TokenStream {
    metrics::armour_metrics_impl(attr, item)
}

mod crate_path;
mod enum_parse;
mod metrics;
mod rapira_field_attrs;
mod struct_parse;

/// - `#[get_type(flatten)]` for unnamed structs
/// - `#[get_type(with_type = Type)]` for named struct fields
/// - `#[get_type(unimplemented)]` for named struct fields
/// - `#[get_type(custom("name", &[Typ::Bool, Typ::Str]))]` for named struct fields
#[proc_macro_derive(GetType, attributes(get_type))]
pub fn derive_get_type(stream: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(stream as DeriveInput);
    if !ast.generics.params.is_empty() {
        return syn::Error::new_spanned(
            &ast.generics,
            "#[derive(GetType)] does not support generic types",
        )
        .to_compile_error()
        .into();
    }
    let name = ast.ident;
    let data = &ast.data;
    let path = crate_path::schema_crate_path();

    match data {
        Data::Struct(data_struct) => struct_parse::parse(data_struct, name, &path).into(),
        Data::Enum(data_enum) => enum_parse::parse(data_enum, name, &path),
        Data::Union(_) => {
            panic!(
                "unions not supported, but Rust enums is implemented GetType trait (use Enums instead)"
            )
        }
    }
}

#[derive(FromMeta, Debug)]
struct CustomField {
    name: LitStr,
    types: Expr,
}

#[derive(Default, FromField, Debug)]
#[darling(attributes(get_type))]
pub(crate) struct FieldAttr {
    pub(crate) with_type: Option<ExprPath>,
    pub(crate) unimplemented: Flag,
    pub(crate) custom: Option<CustomField>,
    pub(crate) flatten: Flag,
}