pub mod entity;
use proc_macro2::TokenStream as TokenStream2;
use quote::{ToTokens, TokenStreamExt, quote};
use syn::ItemMod;
use syn::parse::{Parse, ParseStream};
#[derive(Debug, Clone)]
pub struct Schema {
pub module: ItemMod,
}
impl Schema {
#[cfg(feature = "no-schema-generation")]
fn entity_tokens(&self) -> TokenStream2 {
quote! {}
}
#[cfg(not(feature = "no-schema-generation"))]
fn entity_tokens(&self) -> TokenStream2 {
let ident = &self.module.ident;
let postfix = {
use std::hash::{Hash, Hasher};
let (_content_brace, content_items) =
&self.module.content.as_ref().expect("Can only support `mod {}` right now.");
let mut hasher = std::collections::hash_map::DefaultHasher::new();
content_items.hash(&mut hasher);
hasher.finish()
};
let sql_graph_entity_fn_name = quote::format_ident!("__pgrx_schema_{ident}_{postfix}");
let payload_len = quote! {
::pgrx::pgrx_sql_entity_graph::section::u8_len()
+ ::pgrx::pgrx_sql_entity_graph::section::str_len(module_path!())
+ ::pgrx::pgrx_sql_entity_graph::section::str_len(stringify!(#ident))
+ ::pgrx::pgrx_sql_entity_graph::section::str_len(file!())
+ ::pgrx::pgrx_sql_entity_graph::section::u32_len()
};
let total_len = quote! {
::pgrx::pgrx_sql_entity_graph::section::u32_len() + (#payload_len)
};
quote! {
::pgrx::pgrx_sql_entity_graph::__pgrx_schema_entry!(
#sql_graph_entity_fn_name,
#total_len,
::pgrx::pgrx_sql_entity_graph::section::EntryWriter::<{ #total_len }>::new()
.u32((#payload_len) as u32)
.u8(::pgrx::pgrx_sql_entity_graph::section::ENTITY_SCHEMA)
.str(module_path!())
.str(stringify!(#ident))
.str(file!())
.u32(line!())
.finish()
);
}
}
}
impl ToTokens for Schema {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let attrs = &self.module.attrs;
let vis = &self.module.vis;
let mod_token = &self.module.mod_token;
let ident = &self.module.ident;
let graph_tokens = self.entity_tokens();
let (_content_brace, content_items) =
&self.module.content.as_ref().expect("Can only support `mod {}` right now.");
let code = quote! {
#(#attrs)*
#vis #mod_token #ident {
#(#content_items)*
#graph_tokens
}
};
tokens.append_all(code)
}
}
impl Parse for Schema {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
let module: ItemMod = input.parse()?;
crate::ident_is_acceptable_to_postgres(&module.ident)?;
Ok(Self { module })
}
}