mod crud;
mod handlers;
mod openapi;
mod router;
use proc_macro2::TokenStream;
use quote::quote;
use super::parse::EntityDef;
pub fn generate(entity: &EntityDef) -> TokenStream {
if !entity.has_api() {
return TokenStream::new();
}
let has_crud = entity.api_config().has_handlers();
let has_commands = entity.has_commands() && !entity.command_defs().is_empty();
if !has_crud && !has_commands {
return TokenStream::new();
}
let crud_handlers = crud::generate(entity);
let command_handlers = handlers::generate(entity);
let router = router::generate(entity);
let openapi = openapi::generate(entity);
quote! {
#crud_handlers
#command_handlers
#router
#openapi
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::entity::parse::EntityDef;
#[test]
fn generate_no_api_returns_empty() {
let input: syn::DeriveInput = syn::parse_quote! {
#[entity(table = "users")]
pub struct User {
#[id]
pub id: uuid::Uuid,
}
};
let entity = EntityDef::from_derive_input(&input).unwrap();
let output = generate(&entity);
assert!(output.is_empty());
}
#[test]
fn generate_api_no_handlers_no_commands() {
let input: syn::DeriveInput = syn::parse_quote! {
#[entity(table = "users", api(tag = "Users"))]
pub struct User {
#[id]
pub id: uuid::Uuid,
}
};
let entity = EntityDef::from_derive_input(&input).unwrap();
let output = generate(&entity);
assert!(output.is_empty());
}
#[test]
fn generate_with_handlers() {
let input: syn::DeriveInput = syn::parse_quote! {
#[entity(table = "users", api(tag = "Users", handlers))]
pub struct User {
#[id]
pub id: uuid::Uuid,
#[field(create, update, response)]
pub name: String,
}
};
let entity = EntityDef::from_derive_input(&input).unwrap();
let output = generate(&entity);
assert!(!output.is_empty());
let output_str = output.to_string();
assert!(output_str.contains("user_router"));
assert!(output_str.contains("UserApi"));
}
#[test]
fn generate_with_commands() {
let input: syn::DeriveInput = syn::parse_quote! {
#[entity(table = "users", commands, api(tag = "Users"))]
#[command(Register)]
pub struct User {
#[id]
pub id: uuid::Uuid,
#[field(create, response)]
pub name: String,
}
};
let entity = EntityDef::from_derive_input(&input).unwrap();
let output = generate(&entity);
assert!(!output.is_empty());
}
#[test]
fn generate_with_both_handlers_and_commands() {
let input: syn::DeriveInput = syn::parse_quote! {
#[entity(table = "users", commands, api(tag = "Users", handlers))]
#[command(Activate)]
pub struct User {
#[id]
pub id: uuid::Uuid,
#[field(create, update, response)]
pub name: String,
}
};
let entity = EntityDef::from_derive_input(&input).unwrap();
let output = generate(&entity);
assert!(!output.is_empty());
let output_str = output.to_string();
assert!(output_str.contains("user_router"));
assert!(output_str.contains("UserApi"));
}
}