use crate::compile::case::action::Action;
use crate::compile::matchers::Setup;
use crate::compile::sections::{action::ActionSectionCodeGen, setup::SetupSectionCodeGen};
use crate::parse::context::Context;
use crate::traits::Definition;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::Ident;
pub trait TopLevelCodeGen {
fn generate<A: ActionSectionCodeGen, D: SetupSectionCodeGen>(
def: &dyn Definition,
) -> TokenStream;
}
pub struct TopLevel;
impl TopLevel {}
impl TopLevelCodeGen for TopLevel {
fn generate<A: ActionSectionCodeGen, D: SetupSectionCodeGen>(
def: &dyn Definition,
) -> TokenStream {
let Context {
incoming_message,
mailbox,
..
} = def.context();
let result_name = "result";
let result_ident = Ident::new(result_name, Span::call_site());
let action_section = A::generate::<Action>(def.cases(), result_name);
let setup_section = D::generate::<Setup>(def);
quote! {
if !#mailbox.is_initialized() {
if #mailbox.is_modified() {
panic!("Mailbox was modified prior to initialization");
}
#setup_section
#mailbox.init();
}
if let Some(#result_ident) = #mailbox.process(#incoming_message) {
#action_section
}
()
}
}
}