feat: one-to-many relation helper

Allow one to specify that a field of a model is a foreign key.
It will generate a bunch of helper methods to query related entities
from one entity.
This commit is contained in:
Matthieu Bessat 2025-11-11 17:10:47 +01:00
parent 32ef1f7b33
commit 5f45671b74
25 changed files with 764 additions and 140 deletions

View file

@ -1,4 +1,6 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{DeriveInput, Fields, parse_macro_input};
#[proc_macro_attribute]
pub fn sql_generator_model(_attr: TokenStream, item: TokenStream) -> TokenStream {
@ -6,8 +8,34 @@ pub fn sql_generator_model(_attr: TokenStream, item: TokenStream) -> TokenStream
}
#[proc_macro_derive(SqlGeneratorDerive, attributes(sql_generator_field))]
pub fn sql_generator_field(_item: TokenStream) -> TokenStream {
pub fn derive_sql_generator_model(_input: TokenStream) -> TokenStream {
TokenStream::new()
}
#[proc_macro_derive(SqlGeneratorModelWithId, attributes(sql_generator_field))]
pub fn derive_sql_generator_model_with_id(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
// Extract the fields of the struct
if let syn::Data::Struct(data) = input.data {
if let Fields::Named(fields) = data.fields {
for field in fields.named {
if field.ident.as_ref().map_or(false, |ident| ident == "id") {
let expanded = quote! {
impl DatabaseLine for #name {
fn id(&self) -> String {
self.id.clone()
}
}
};
return TokenStream::from(expanded);
}
}
}
}
// If `id` field is not found, return an error
panic!("Expected struct with a named field `id` of type String")
}