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