pub mod declaration;
pub mod expand;
pub use declaration::ApplicationDeclaration;
use proc_macro2::TokenStream;
use crate::diagnostic::{MacroError, MacroErrorCode, MacroResult};
pub fn application(input: TokenStream) -> MacroResult {
let declaration: ApplicationDeclaration =
syn::parse2(input).map_err(|e| MacroError::from_syn(MacroErrorCode::ArcM001, e))?;
declaration::validate(&declaration)?;
Ok(expand::expand(&declaration))
}
#[cfg(test)]
mod tests {
use super::*;
use quote::quote;
#[test]
fn expands_a_full_application_declaration() {
let s = application(quote! {
pub App {
modules: [accounts::accounts_module],
routes: [accounts::routes],
state: AppState,
page_contracts: [home::HomePage],
}
})
.unwrap()
.to_string();
assert!(s.contains("fn app_graph ()"), "got: {s}");
assert!(s.contains("fn app_routes ()"), "got: {s}");
assert!(s.contains("fn app_page_contracts ()"), "got: {s}");
}
#[test]
fn reports_a_syntax_error_as_arc_m001() {
let err = application(quote! { pub App { widgets: [X] } }).unwrap_err();
assert_eq!(err.code(), MacroErrorCode::ArcM001);
}
#[test]
fn reports_a_duplicate_module_as_arc_m002() {
let err = application(quote! { App { modules: [a::m, a::m] } }).unwrap_err();
assert_eq!(err.code(), MacroErrorCode::ArcM002);
}
}