gel-derive 0.7.4

Derive macros for Gel database client. Formerly published as gel-derive.
Documentation
use proc_macro2::TokenStream;
use quote::quote;

use crate::attrib::ContainerAttrs;

pub fn derive(item: &syn::Item, container_attrs: &ContainerAttrs) -> syn::Result<TokenStream> {
    let gel_protocol = container_attrs.gel_protocol_path();
    let (name, impl_generics, ty_generics) = match item {
        syn::Item::Struct(s) => {
            let (impl_generics, ty_generics, _) = s.generics.split_for_impl();
            (&s.ident, impl_generics, ty_generics)
        }
        syn::Item::Enum(e) => {
            let (impl_generics, ty_generics, _) = e.generics.split_for_impl();
            (&e.ident, impl_generics, ty_generics)
        }
        _ => {
            return Err(syn::Error::new_spanned(
                item,
                "can only derive Queryable for structs and enums in JSON mode",
            ));
        }
    };
    let expanded = quote! {
        impl #impl_generics #gel_protocol::queryable::Queryable
            for #name #ty_generics {
            type Args = ();

            fn decode(decoder: &#gel_protocol::queryable::Decoder, _args: &(), buf: &[u8])
                -> Result<Self, #gel_protocol::errors::DecodeError>
            {
                let json: #gel_protocol::model::Json =
                    #gel_protocol::queryable::Queryable::decode(decoder, &(), buf)?;
                ::serde_json::from_str(json.as_ref())
                    .map_err(#gel_protocol::errors::decode_error)
            }
            fn check_descriptor(
                ctx: &#gel_protocol::queryable::DescriptorContext,
                type_pos: #gel_protocol::descriptors::TypePos)
                -> Result<(), #gel_protocol::queryable::DescriptorMismatch>
            {
                <#gel_protocol::model::Json as
                    #gel_protocol::queryable::Queryable>
                    ::check_descriptor(ctx, type_pos)
            }
        }
    };
    Ok(expanded)
}