use std::{ error::Error, fmt::{Debug, Display}, }; use anyhow::Result; use crate::{ compile::{Compile, CompileContext}, ir::Definition, IR, }; pub mod rust; pub mod typescript; #[derive(Debug, Clone)] pub struct CompilerError { pub message: String, pub definition: D, } impl CompilerError { fn new(msg: &str, definition: D) -> Self { Self { message: format!("{}: {}", msg, definition.get_name()), definition, } } } impl Error for CompilerError {} impl Display for CompilerError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "CompilerError: {} at {:?}", self.message, self.definition.get_position() ) } } pub fn compile(ir: IR, output: &str) -> Result<()> { let mut ctx = CompileContext::new(output); let mut compiler = T::new(&ir.options)?; compiler.start(&mut ctx)?; for step in ir.steps.iter() { match step { crate::ir::Step::Type(definition) => { match compiler.generate_type(&mut ctx, &definition) { Ok(_) => (), Err(err) => { return Err(CompilerError::new(&err.to_string(), definition.clone()).into()) } } } crate::ir::Step::Enum(definition) => { match compiler.generate_enum(&mut ctx, &definition) { Ok(_) => (), Err(err) => { return Err(CompilerError::new(&err.to_string(), definition.clone()).into()) } } } crate::ir::Step::Service(definition) => { match compiler.generate_service(&mut ctx, &definition) { Ok(_) => (), Err(err) => { return Err(CompilerError::new(&err.to_string(), definition.clone()).into()) } } } } } compiler.finalize(&mut ctx, &ir)?; Ok(()) }