autapi 0.0.1

Automatic OpenAPI specification from function signatures
Documentation
use crate::schema::SchemaDeserialize;
use crate::{
    Registry,
    openapi::{MaybeRef, Schema},
    schema::{
        ToSchema,
        macros::{transparent_deserialize, transparent_serialize},
    },
};
use serde::Deserializer;
use std::{borrow::Cow, cell::RefCell, ops::Deref, rc::Rc, sync::Arc};

macro_rules! impl_transparent {
    (
        $ty:ident <
            $($lt:lifetime,)?
            T $(: $($bound:ident)*)?
        > via $func:expr
    ) => {
        impl_transparent!(
            @no_deserialize
            $ty < $($lt,)? T $(: $($bound)*)? >
            via $func
        );
        transparent_deserialize!(schema $ty<$($lt;)? T $(: $($bound)*)?> via T);
    };
    (
        @no_deserialize
        $ty:ident <
            $($lt:lifetime,)?
            T $(: $($bound:ident)*)?
        > via $func:expr
    ) => {
        impl<$($lt,)? T: ?Sized> ToSchema for $ty<$($lt,)? T>
        where
            T: ToSchema,
            $($(T: $bound,)*)?
        {
            type Original = T::Original;

            const REQUIRED: bool = T::REQUIRED;
            const ALWAYS_INLINED: bool = T::ALWAYS_INLINED;

            fn name() -> Cow<'static, str> {
                T::name()
            }
            fn schema(registry: &mut Registry) -> MaybeRef<Schema> {
                T::schema(registry)
            }

            fn schema_ref(registry: &mut Registry) -> MaybeRef<Schema> {
                T::schema_ref(registry)
            }
        }

        transparent_serialize!(schema $ty<$($lt;)? T $(: $($bound)*)?> via T <- $func);
    };
}

impl_transparent!(Box<T> via Deref::deref);
impl_transparent!(Arc<T> via Deref::deref);
impl_transparent!(Rc<T> via Deref::deref);
impl_transparent!(RefCell<T> via RefCell::borrow);
impl_transparent!(@no_deserialize Cow<'a, T: ToOwned> via Deref::deref);

impl<'a, T> SchemaDeserialize for Cow<'a, T>
where
    T: ?Sized + ToOwned + ToSchema,
    T::Owned: SchemaDeserialize + ToSchema<Original = T::Original>,
{
    fn schema_deserialize<'de, D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        Ok(Cow::Owned(T::Owned::schema_deserialize(deserializer)?))
    }

    fn deserialize_missing() -> Option<Self> {
        Some(Cow::Owned(T::Owned::deserialize_missing()?))
    }
}

type Ref<'a, T> = &'a T;
impl_transparent!(@no_deserialize Ref<'a, T> via Deref::deref);