predawn-macro 0.9.0

Macros for predawn
Documentation
use from_attr::{AttrsValue, FromAttr};
use proc_macro2::TokenStream;
use quote::quote;
use quote_use::quote_use;
use syn::DeriveInput;

use crate::util;

#[derive(FromAttr, Default)]
#[attribute(idents = [tag])]
struct TypeAttr {
    rename: Option<String>,
}

pub(crate) fn generate(input: DeriveInput) -> syn::Result<TokenStream> {
    let DeriveInput { attrs, ident, .. } = input;

    let TypeAttr { rename } = match TypeAttr::from_attributes(&attrs) {
        Ok(Some(AttrsValue {
            value: type_attr, ..
        })) => type_attr,
        Ok(None) => Default::default(),
        Err(AttrsValue { value: e, .. }) => return Err(e),
    };

    let ident_str = rename.unwrap_or_else(|| ident.to_string());

    let description = util::extract_description(&attrs);
    let description = if description.is_empty() {
        quote! { None }
    } else {
        let description = util::generate_string_expr(&description);
        quote! { Some(#description) }
    };

    let expand = quote_use! {
        # use core::default::Default;
        # use std::string::ToString;
        # use predawn::Tag;
        # use predawn::openapi;

        impl Tag for #ident {
            const NAME: &'static str = #ident_str;

            fn create() -> openapi::Tag {
                openapi::Tag {
                    name: ToString::to_string(Self::NAME),
                    description: #description,
                    external_docs: Default::default(),
                    extensions: Default::default(),
                }
            }
        }
    };

    Ok(expand)
}