autapi-macros 0.0.1

Macros for autapi
Documentation
use darling::{FromDeriveInput, FromField, FromMeta, FromVariant, util::Flag};
use syn::{Generics, Ident, LitStr, Type};

use crate::{
    doc_attr::DocAttr,
    utils::{Case, ExprsMeta, PreserveStringExpr},
};

#[derive(Debug, Clone, FromDeriveInput)]
#[darling(attributes(schema), forward_attrs(doc))]
pub struct DeriveToSchemaAttrs<I> {
    pub ident: Ident,
    pub generics: Generics,
    pub bounds: Option<LitStr>,

    pub rename: Option<LitStr>,
    pub always_inlined: Flag,

    pub no_serialize: Flag,
    pub no_deserialize: Flag,

    pub serde: Flag,

    #[darling(with = DocAttr::try_from)]
    pub attrs: DocAttr,
    #[darling(flatten)]
    pub inner: I,
}

pub type NamedFieldsStructAttrs = DeriveToSchemaAttrs<NamedFieldsAttrs>;
pub type TupleStructAttrs = DeriveToSchemaAttrs<FieldAttrs>;
pub type UnitStructAttrs = DeriveToSchemaAttrs<SchemaMetaAttrs>;
pub type EnumAttrs = DeriveToSchemaAttrs<EnumAttrsInner>;

#[derive(Debug, Clone, FromMeta)]
pub struct EnumAttrsInner {
    pub tag: Option<LitStr>,
    pub untagged: Flag,
    pub rename_all: Option<Case>,
    pub rename_all_fields: Option<Case>,
    #[darling(flatten)]
    pub meta: SchemaMetaAttrs,
}

#[derive(Debug, Clone, FromVariant)]
#[darling(attributes(schema), forward_attrs(doc))]
pub struct EnumVariantAttrs<I> {
    pub ident: Ident,
    pub rename: Option<LitStr>,
    pub untagged: Flag,
    #[darling(with = DocAttr::try_from)]
    pub attrs: DocAttr,
    #[darling(flatten)]
    pub inner: I,
}

pub type NamedFieldsEnumVariantAttrs = EnumVariantAttrs<NamedFieldsAttrs>;
pub type TupleEnumVariantAttrs = EnumVariantAttrs<FieldAttrs>;
pub type UnitEnumVariantAttrs = EnumVariantAttrs<UnitEnumVariantAttrsInner>;

#[derive(Debug, Clone, FromMeta)]
pub struct UnitEnumVariantAttrsInner {
    pub null: Flag,
    #[darling(flatten)]
    pub meta: SchemaMetaAttrs,
}

#[derive(Debug, Clone, FromMeta)]
pub struct NamedFieldsAttrs {
    pub rename_all: Option<Case>,
    #[darling(flatten)]
    pub meta: SchemaMetaAttrs,
}

#[derive(Debug, Clone, FromField)]
#[darling(attributes(schema), forward_attrs(doc))]
pub struct NamedFieldAttrs {
    pub ty: Type,
    pub skip: Flag,
    pub rename: Option<LitStr>,
    #[darling(with = DocAttr::try_from)]
    pub attrs: DocAttr,
    #[darling(flatten)]
    pub inner: FieldAttrs,
}

#[derive(Debug, Clone, FromMeta)]
pub struct FieldAttrs {
    pub inline: Flag,
    pub using: Option<String>,
    pub optional: Flag,
    pub nullable: Flag,
    #[darling(flatten)]
    pub meta: SchemaMetaAttrs,
}

#[derive(Debug, Clone, FromMeta)]
pub struct SchemaMetaAttrs {
    pub description: Option<LitStr>,
    pub title: Option<LitStr>,
    pub deprecated: Flag,
    pub read_only: Flag,
    pub write_only: Flag,
    pub example: Option<PreserveStringExpr>,
    pub examples: Option<ExprsMeta>,
}

impl SchemaMetaAttrs {
    pub fn any_set(&self) -> bool {
        let Self {
            description,
            title,
            deprecated,
            read_only,
            write_only,
            example,
            examples,
        } = self;
        description.is_some()
            || title.is_some()
            || deprecated.is_present()
            || read_only.is_present()
            || write_only.is_present()
            || example.is_some()
            || examples.is_some()
    }
    pub fn or_with_doc_description(self, docs: &DocAttr) -> Self {
        Self {
            description: self.description.or_else(|| docs.to_lines()),
            ..self
        }
    }
}