pgx_sql_entity_graph/pg_extern/
argument.rs1use crate::UsedType;
18use proc_macro2::{Span, TokenStream as TokenStream2};
19use quote::{quote, ToTokens, TokenStreamExt};
20use syn::{FnArg, Pat};
21
22#[derive(Debug, Clone)]
26pub struct PgExternArgument {
27 pub fn_arg: syn::FnArg,
28 pub pat: syn::Ident,
29 pub used_ty: UsedType,
30}
31
32impl PgExternArgument {
33 pub fn build(fn_arg: FnArg) -> Result<Self, syn::Error> {
34 match &fn_arg {
35 syn::FnArg::Typed(pat) => Self::build_from_pat_type(fn_arg.clone(), pat.clone()),
36 syn::FnArg::Receiver(_) => {
37 Err(syn::Error::new(Span::call_site(), "Unable to parse FnArg that is Self"))
38 }
39 }
40 }
41
42 pub fn build_from_pat_type(
43 fn_arg: syn::FnArg,
44 value: syn::PatType,
45 ) -> Result<Self, syn::Error> {
46 let identifier = match *value.pat {
47 Pat::Ident(ref p) => p.ident.clone(),
48 Pat::Reference(ref p_ref) => match *p_ref.pat {
49 Pat::Ident(ref inner_ident) => inner_ident.ident.clone(),
50 _ => return Err(syn::Error::new(Span::call_site(), "Unable to parse FnArg")),
51 },
52 _ => return Err(syn::Error::new(Span::call_site(), "Unable to parse FnArg")),
53 };
54
55 let used_ty = UsedType::new(*value.ty)?;
56
57 Ok(PgExternArgument { fn_arg, pat: identifier, used_ty })
58 }
59
60 pub fn entity_tokens(&self) -> TokenStream2 {
61 let pat = &self.pat;
62 let used_ty_entity = self.used_ty.entity_tokens();
63
64 let quoted = quote! {
65 ::pgx::pgx_sql_entity_graph::PgExternArgumentEntity {
66 pattern: stringify!(#pat),
67 used_ty: #used_ty_entity,
68 }
69 };
70 quoted
71 }
72}
73
74impl ToTokens for PgExternArgument {
75 fn to_tokens(&self, tokens: &mut TokenStream2) {
76 let fn_arg = &self.fn_arg;
77 let quoted = quote! {
78 #fn_arg
79 };
80 tokens.append_all(quoted);
81 }
82}