use proc_macro2::{Span, TokenStream}; use quote::quote; use std::iter; use syn::Ident; use crate::composites::Field; use crate::enums::Variant; pub fn domain_body(name: &str, field: &syn::Field) -> TokenStream { let ty = &field.ty; quote! { if type_.name() != #name { return false; } match *type_.kind() { ::postgres_types::Kind::Domain(ref type_) => { <#ty as ::postgres_types::ToSql>::accepts(type_) } _ => false, } } } pub fn enum_body(name: &str, variants: &[Variant]) -> TokenStream { let num_variants = variants.len(); let variant_names = variants.iter().map(|v| &v.name); quote! { if type_.name() != #name { return false; } match *type_.kind() { ::postgres_types::Kind::Enum(ref variants) => { if variants.len() != #num_variants { return false; } variants.iter().all(|v| { match &**v { #( #variant_names => true, )* _ => false, } }) } _ => false, } } } pub fn composite_body(name: &str, trait_: &str, fields: &[Field]) -> TokenStream { let num_fields = fields.len(); let trait_ = Ident::new(trait_, Span::call_site()); let traits = iter::repeat(&trait_); let field_names = fields.iter().map(|f| &f.name); let field_types = fields.iter().map(|f| &f.type_); quote! { if type_.name() != #name { return false; } match *type_.kind() { ::postgres_types::Kind::Composite(ref fields) => { if fields.len() != #num_fields { return false; } fields.iter().all(|f| { match f.name() { #( #field_names => { <#field_types as ::postgres_types::#traits>::accepts(f.type_()) } )* _ => false, } }) } _ => false, } } }