Skip to main content

alef_codegen/generators/
enums.rs

1use crate::generators::RustBindingConfig;
2use alef_core::ir::EnumDef;
3use std::fmt::Write;
4
5/// Generate an enum.
6pub fn gen_enum(enum_def: &EnumDef, cfg: &RustBindingConfig) -> String {
7    // All enums are generated as unit-variant-only in the binding layer.
8    // Data variants are flattened to unit variants; the From/Into conversions
9    // handle the lossy mapping (discarding / providing defaults for field data).
10    let mut out = String::with_capacity(512);
11    let mut derives: Vec<&str> = cfg.enum_derives.to_vec();
12    if cfg.has_serde {
13        derives.push("serde::Serialize");
14    }
15    if !derives.is_empty() {
16        writeln!(out, "#[derive({})]", derives.join(", ")).ok();
17    }
18    for attr in cfg.enum_attrs {
19        writeln!(out, "#[{attr}]").ok();
20    }
21    writeln!(out, "pub enum {} {{", enum_def.name).ok();
22    for (idx, variant) in enum_def.variants.iter().enumerate() {
23        writeln!(out, "    {} = {idx},", variant.name).ok();
24    }
25    writeln!(out, "}}").ok();
26
27    // Generate Default impl (first variant) so enums can be used with unwrap_or_default()
28    // in config constructors for types with has_default.
29    if let Some(first) = enum_def.variants.first() {
30        writeln!(out).ok();
31        writeln!(out, "#[allow(clippy::derivable_impls)]").ok();
32        writeln!(out, "impl Default for {} {{", enum_def.name).ok();
33        writeln!(out, "    fn default() -> Self {{ Self::{} }}", first.name).ok();
34        writeln!(out, "}}").ok();
35    }
36
37    out
38}