use syn::Ident;
const ATTRIBUTE_TABLES: &str = "tables";
pub struct SchemaMetadata {
pub tables: Vec<TableEntry>,
}
pub struct TableEntry {
pub table: Ident,
pub insert: Ident,
pub update: Ident,
}
pub fn collect_schema_metadata(attrs: &[syn::Attribute]) -> syn::Result<SchemaMetadata> {
let mut tables = Vec::new();
let mut names = vec![];
for attr in attrs {
if attr.path().is_ident(ATTRIBUTE_TABLES) {
attr.parse_nested_meta(|meta| {
let ident = meta
.path
.get_ident()
.cloned()
.ok_or_else(|| meta.error("expected identifier"))?;
let value: syn::LitStr = meta.value()?.parse()?;
let value = value.value();
names.push((ident, value));
Ok(())
})?;
}
}
for (ident, _) in names {
tables.push(collect_table_entry(ident)?);
}
Ok(SchemaMetadata { tables })
}
fn collect_table_entry(table: Ident) -> syn::Result<TableEntry> {
let insert_ident = Ident::new(&format!("{table}InsertRequest"), table.span());
let update_ident = Ident::new(&format!("{table}UpdateRequest"), table.span());
Ok(TableEntry {
table: table.clone(),
insert: insert_ident,
update: update_ident,
})
}