microtype-macro 0.2.1

Proc macro for generating microtypes
Documentation
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Attribute, Ident, Type};

use crate::parse::DieselTypeAttr;

#[allow(dead_code)]
fn parse_diesel_attr(attr: &Attribute) -> Option<Ident> {
    if attr.path.get_ident().map(Ident::to_string) == Some("sql_type".into()) {
        match attr.parse_args::<DieselTypeAttr>() {
            Ok(DieselTypeAttr { ty }) => Some(ty),
            _ => None,
        }
    } else {
        None
    }
}

#[allow(dead_code)]
pub fn generate_diesel_impls(
    inner: Type,
    name: Ident,
    attrs: &[Attribute],
    secret: bool,
) -> TokenStream {
    let new = if secret {
        quote! {
            <#name as ::microtype::SecretMicrotype>::new
        }
    } else {
        quote! {
            <#name as ::microtype::Microtype>::new
        }
    };

    let from = if secret {
        quote! {
            <#name as ::microtype::secrecy::ExposeSecret<#inner>>::expose_secret(self)
        }
    } else {
        quote! {
            <#name as ::microtype::Microtype>::inner(self)
        }
    };


    let attr = attrs.iter().find_map(parse_diesel_attr);

    match attr {
        None => quote! {},
        Some(diesel_type) => {
            quote! {
                impl<B: ::diesel::backend::Backend> ::diesel::types::FromSql<#diesel_type, B> for #name {
                    fn from_sql(bytes: ::std::option::Option<&B::RawValue>) -> ::diesel::deserialize::Result<Self> {
                        <#inner as ::diesel::types::FromSql<$diesel, B>::from_sql(bytes).map(#new)
                    }
                }

                impl<B: ::diesel::backend::Backend> ::diesel::types::ToSql<#diesel_type, B> for #name {
                    fn to_sql<W: ::std::io::Write>(
                            &self,
                            out: &mut ::diesel::serialize::Output<W, B>,
                        ) -> ::diesel::serialize::Result {

                        <#inner as ToSql<#diesel_type, B>::to_sql(
                            #from
                            out,
                        )

                    }
                }
            }
        }
    }
}