pgrx_sql_entity_graph/postgres_ord/
mod.rs1pub mod entity;
19
20use crate::enrich::{ToEntityGraphTokens, ToRustCodeTokens};
21use proc_macro2::TokenStream as TokenStream2;
22use quote::{format_ident, quote};
23use syn::parse::{Parse, ParseStream};
24use syn::{DeriveInput, Ident};
25
26use crate::{CodeEnrichment, ToSqlConfig};
27
28#[derive(Debug, Clone)]
74pub struct PostgresOrd {
75 pub name: Ident,
76 pub to_sql_config: ToSqlConfig,
77}
78
79impl PostgresOrd {
80 pub fn new(
81 name: Ident,
82 to_sql_config: ToSqlConfig,
83 ) -> Result<CodeEnrichment<Self>, syn::Error> {
84 if !to_sql_config.overrides_default() {
85 crate::ident_is_acceptable_to_postgres(&name)?;
86 }
87
88 Ok(CodeEnrichment(Self { name, to_sql_config }))
89 }
90
91 pub fn from_derive_input(
92 derive_input: DeriveInput,
93 ) -> Result<CodeEnrichment<Self>, syn::Error> {
94 let to_sql_config =
95 ToSqlConfig::from_attributes(derive_input.attrs.as_slice())?.unwrap_or_default();
96 Self::new(derive_input.ident, to_sql_config)
97 }
98}
99
100impl ToEntityGraphTokens for PostgresOrd {
101 fn to_entity_graph_tokens(&self) -> TokenStream2 {
102 let name = &self.name;
103 let sql_graph_entity_fn_name = format_ident!("__pgrx_schema_ord_{}", self.name);
104 let to_sql_config = &self.to_sql_config;
105 let to_sql_config_len = to_sql_config.section_len_tokens();
106 let payload_len = quote! {
107 ::pgrx::pgrx_sql_entity_graph::section::u8_len()
108 + ::pgrx::pgrx_sql_entity_graph::section::str_len(stringify!(#name))
109 + ::pgrx::pgrx_sql_entity_graph::section::str_len(file!())
110 + ::pgrx::pgrx_sql_entity_graph::section::u32_len()
111 + ::pgrx::pgrx_sql_entity_graph::section::str_len(stringify!(#name))
112 + ::pgrx::pgrx_sql_entity_graph::section::str_len(module_path!())
113 + ::pgrx::pgrx_sql_entity_graph::section::str_len(<#name as ::pgrx::pgrx_sql_entity_graph::metadata::SqlTranslatable>::TYPE_IDENT)
114 + (#to_sql_config_len)
115 };
116 let total_len = quote! {
117 ::pgrx::pgrx_sql_entity_graph::section::u32_len() + (#payload_len)
118 };
119 let writer = to_sql_config.section_writer_tokens(quote! {
120 ::pgrx::pgrx_sql_entity_graph::section::EntryWriter::<{ #total_len }>::new()
121 .u32((#payload_len) as u32)
122 .u8(::pgrx::pgrx_sql_entity_graph::section::ENTITY_ORD)
123 .str(stringify!(#name))
124 .str(file!())
125 .u32(line!())
126 .str(stringify!(#name))
127 .str(module_path!())
128 .str(<#name as ::pgrx::pgrx_sql_entity_graph::metadata::SqlTranslatable>::TYPE_IDENT)
129 });
130 quote! {
131 ::pgrx::pgrx_sql_entity_graph::__pgrx_schema_entry!(
132 #sql_graph_entity_fn_name,
133 #total_len,
134 #writer.finish()
135 );
136 }
137 }
138}
139
140impl ToRustCodeTokens for PostgresOrd {}
141
142impl Parse for CodeEnrichment<PostgresOrd> {
143 fn parse(input: ParseStream) -> Result<Self, syn::Error> {
144 use syn::Item;
145
146 let parsed = input.parse()?;
147 let (ident, attrs) = match &parsed {
148 Item::Enum(item) => (item.ident.clone(), item.attrs.as_slice()),
149 Item::Struct(item) => (item.ident.clone(), item.attrs.as_slice()),
150 _ => return Err(syn::Error::new(input.span(), "expected enum or struct")),
151 };
152 let to_sql_config = ToSqlConfig::from_attributes(attrs)?.unwrap_or_default();
153 PostgresOrd::new(ident, to_sql_config)
154 }
155}