pgx_sql_entity_graph/
lifetimes.rs1use crate::NameMacro;
2use proc_macro2::TokenStream;
3
4pub fn staticize_lifetimes_in_type_path(value: syn::TypePath) -> syn::TypePath {
5 let mut ty = syn::Type::Path(value);
6 staticize_lifetimes(&mut ty);
7 match ty {
8 syn::Type::Path(type_path) => type_path,
9
10 _ => panic!("not a TypePath"),
12 }
13}
14
15pub fn staticize_lifetimes(value: &mut syn::Type) {
16 match value {
17 syn::Type::Path(type_path) => {
18 for segment in &mut type_path.path.segments {
19 match &mut segment.arguments {
20 syn::PathArguments::AngleBracketed(bracketed) => {
21 for arg in &mut bracketed.args {
22 match arg {
23 syn::GenericArgument::Lifetime(lifetime) => {
25 lifetime.ident =
26 syn::Ident::new("static", lifetime.ident.span());
27 }
28
29 syn::GenericArgument::Type(ty) => staticize_lifetimes(ty),
31 syn::GenericArgument::Binding(binding) => {
32 staticize_lifetimes(&mut binding.ty)
33 }
34 syn::GenericArgument::Constraint(constraint) => {
35 for bound in constraint.bounds.iter_mut() {
36 match bound {
37 syn::TypeParamBound::Lifetime(lifetime) => {
38 lifetime.ident =
39 syn::Ident::new("static", lifetime.ident.span())
40 }
41 _ => {}
42 }
43 }
44 }
45
46 _ => {}
48 }
49 }
50 }
51 _ => {}
52 }
53 }
54 }
55
56 syn::Type::Reference(type_ref) => match &mut type_ref.lifetime {
57 Some(ref mut lifetime) => {
58 lifetime.ident = syn::Ident::new("static", lifetime.ident.span());
59 }
60 this @ None => *this = Some(syn::parse_quote!('static)),
61 },
62
63 syn::Type::Tuple(type_tuple) => {
64 for elem in &mut type_tuple.elems {
65 staticize_lifetimes(elem);
66 }
67 }
68
69 syn::Type::Macro(type_macro) => {
70 let mac = &type_macro.mac;
71 if let Some(archetype) = mac.path.segments.last() {
72 match archetype.ident.to_string().as_str() {
73 "name" => {
74 if let Ok(out) = mac.parse_body::<NameMacro>() {
75 if let Ok(ident) = syn::parse_str::<TokenStream>(&out.ident) {
80 let mut ty = out.used_ty.resolved_ty;
81
82 staticize_lifetimes(&mut ty);
84 type_macro.mac = syn::parse_quote! {::pgx::name!(#ident, #ty)};
85 }
86 }
87 }
88 _ => {}
89 }
90 }
91 }
92 _ => {}
93 }
94}
95
96pub fn anonymize_lifetimes_in_type_path(value: syn::TypePath) -> syn::TypePath {
97 let mut ty = syn::Type::Path(value);
98 anonymize_lifetimes(&mut ty);
99 match ty {
100 syn::Type::Path(type_path) => type_path,
101
102 _ => panic!("not a TypePath"),
104 }
105}
106
107pub fn anonymize_lifetimes(value: &mut syn::Type) {
108 match value {
109 syn::Type::Path(type_path) => {
110 for segment in &mut type_path.path.segments {
111 match &mut segment.arguments {
112 syn::PathArguments::AngleBracketed(bracketed) => {
113 for arg in &mut bracketed.args {
114 match arg {
115 syn::GenericArgument::Lifetime(lifetime) => {
117 lifetime.ident = syn::Ident::new("_", lifetime.ident.span());
118 }
119
120 syn::GenericArgument::Type(ty) => anonymize_lifetimes(ty),
122 syn::GenericArgument::Binding(binding) => {
123 anonymize_lifetimes(&mut binding.ty)
124 }
125 syn::GenericArgument::Constraint(constraint) => {
126 for bound in constraint.bounds.iter_mut() {
127 match bound {
128 syn::TypeParamBound::Lifetime(lifetime) => {
129 lifetime.ident =
130 syn::Ident::new("_", lifetime.ident.span())
131 }
132 _ => {}
133 }
134 }
135 }
136
137 _ => {}
139 }
140 }
141 }
142 _ => {}
143 }
144 }
145 }
146
147 syn::Type::Reference(type_ref) => {
148 if let Some(lifetime) = type_ref.lifetime.as_mut() {
149 lifetime.ident = syn::Ident::new("_", lifetime.ident.span());
150 }
151 }
152
153 syn::Type::Tuple(type_tuple) => {
154 for elem in &mut type_tuple.elems {
155 anonymize_lifetimes(elem);
156 }
157 }
158
159 _ => {}
160 }
161}