1pub mod rust;
8
9use crate::config::GenTarget;
10use crate::types::ValidatedDef;
11
12pub trait CodegenBackend {
14 fn lang(&self) -> &str;
16
17 fn validate_lang_options(&self, options: &toml::Value) -> Result<(), Vec<String>>;
20
21 fn generate(&self, ir: &ValidatedDef, config: &GenTarget) -> Result<String, CodegenError>;
23
24 fn formatter_command(&self) -> Option<&[&str]>;
26}
27
28#[derive(Debug)]
29pub enum CodegenError {
30 Internal(String),
31}
32
33impl std::fmt::Display for CodegenError {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 match self {
36 CodegenError::Internal(msg) => write!(f, "codegen error: {}", msg),
37 }
38 }
39}
40
41impl std::error::Error for CodegenError {}
42
43pub fn get_backend(lang: &str) -> Option<Box<dyn CodegenBackend>> {
45 match lang {
46 "rust" => Some(Box::new(rust::RustBackend)),
47 _ => None,
48 }
49}
50
51pub fn run_formatter(cmd: &[&str], path: &str) {
53 let status = std::process::Command::new(cmd[0])
54 .args(&cmd[1..])
55 .arg(path)
56 .status();
57
58 match status {
59 Ok(s) if s.success() => {}
60 Ok(s) => eprintln!("warning: formatter exited with {}", s),
61 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
62 eprintln!("warning: formatter '{}' not found, skipping", cmd[0]);
63 }
64 Err(e) => eprintln!("warning: failed to run formatter: {}", e),
65 }
66}