postgres_derive/
accepts.rs1use proc_macro2::{Span, TokenStream};
2use quote::quote;
3use std::iter;
4use syn::Ident;
5
6use crate::composites::Field;
7use crate::enums::Variant;
8
9pub fn transparent_body(field: &syn::Field) -> TokenStream {
10 let ty = &field.ty;
11
12 quote! {
13 <#ty as ::postgres_types::ToSql>::accepts(type_)
14 }
15}
16
17pub fn domain_body(name: &str, field: &syn::Field) -> TokenStream {
18 let ty = &field.ty;
19
20 quote! {
21 if type_.name() != #name {
22 return false;
23 }
24
25 match *type_.kind() {
26 ::postgres_types::Kind::Domain(ref type_) => {
27 <#ty as ::postgres_types::ToSql>::accepts(type_)
28 }
29 _ => false,
30 }
31 }
32}
33
34pub fn enum_body(name: &str, variants: &[Variant], allow_mismatch: bool) -> TokenStream {
35 let num_variants = variants.len();
36 let variant_names = variants.iter().map(|v| &v.name);
37
38 if allow_mismatch {
39 quote! {
40 type_.name() == #name
41 }
42 } else {
43 quote! {
44 if type_.name() != #name {
45 return false;
46 }
47
48 match *type_.kind() {
49 ::postgres_types::Kind::Enum(ref variants) => {
50 if variants.len() != #num_variants {
51 return false;
52 }
53
54 variants.iter().all(|v| {
55 match &**v {
56 #(
57 #variant_names => true,
58 )*
59 _ => false,
60 }
61 })
62 }
63 _ => false,
64 }
65 }
66 }
67}
68
69pub fn composite_body(name: &str, trait_: &str, fields: &[Field]) -> TokenStream {
70 let num_fields = fields.len();
71 let trait_ = Ident::new(trait_, Span::call_site());
72 let traits = iter::repeat(&trait_);
73 let field_names = fields.iter().map(|f| &f.name);
74 let field_types = fields.iter().map(|f| &f.type_);
75
76 quote! {
77 if type_.name() != #name {
78 return false;
79 }
80
81 match *type_.kind() {
82 ::postgres_types::Kind::Composite(ref fields) => {
83 if fields.len() != #num_fields {
84 return false;
85 }
86
87 fields.iter().all(|f| {
88 match f.name() {
89 #(
90 #field_names => {
91 <#field_types as ::postgres_types::#traits>::accepts(f.type_())
92 }
93 )*
94 _ => false,
95 }
96 })
97 }
98 _ => false,
99 }
100 }
101}