vexil_codegen_ts/
enum_gen.rs1use vexil_lang::ir::{EnumDef, TypeRegistry};
2
3use crate::emit::CodeWriter;
4
5pub fn emit_enum(w: &mut CodeWriter, en: &EnumDef, _registry: &TypeRegistry) {
7 let name = en.name.as_str();
8 let wire_bits = en.wire_bits;
9 let non_exhaustive = en.annotations.non_exhaustive;
10
11 if non_exhaustive {
13 let literals: Vec<String> = en
15 .variants
16 .iter()
17 .map(|v| format!("'{}'", v.name))
18 .collect();
19 let mut all = literals;
20 all.push("string".to_string());
21 w.line(&format!("export type {name} = {};", all.join(" | ")));
22 } else {
23 let literals: Vec<String> = en
24 .variants
25 .iter()
26 .map(|v| format!("'{}'", v.name))
27 .collect();
28 w.line(&format!("export type {name} = {};", literals.join(" | ")));
29 }
30
31 w.open_block(&format!("export const {name} ="));
33 for variant in &en.variants {
34 w.line(&format!("{}: '{}' as const,", variant.name, variant.name));
35 }
36 w.dedent();
37 w.line("} as const;");
38 w.blank();
39
40 w.open_block(&format!(
42 "export function encode{name}(v: {name}, w: BitWriter): void"
43 ));
44 w.line("let disc: number;");
46 w.open_block("switch (v)");
47 for variant in &en.variants {
48 w.line(&format!(
49 "case '{}': disc = {}; break;",
50 variant.name, variant.ordinal
51 ));
52 }
53 w.line(&format!(
54 "default: throw new Error(`Unknown {name} variant: ${{v}}`);",
55 ));
56 w.close_block();
57 w.line(&format!("w.writeBits(disc, {wire_bits});"));
58 w.close_block();
59 w.blank();
60
61 w.open_block(&format!(
63 "export function decode{name}(r: BitReader): {name}"
64 ));
65 w.line(&format!("const disc = r.readBits({wire_bits});"));
66 w.open_block("switch (disc)");
67 for variant in &en.variants {
68 w.line(&format!(
69 "case {}: return '{}';",
70 variant.ordinal, variant.name
71 ));
72 }
73 if non_exhaustive {
74 w.line("default: return `Unknown(${disc})`;");
75 } else {
76 w.line(&format!(
77 "default: throw new Error(`Unknown {name} discriminant: ${{disc}}`);",
78 ));
79 }
80 w.close_block();
81 w.close_block();
82 w.blank();
83}