vexil_codegen_rust/
types.rs1use std::collections::HashSet;
2use vexil_lang::ast::{PrimitiveType, SemanticType, SubByteType};
3use vexil_lang::ir::{ResolvedType, TypeDef, TypeId, TypeRegistry};
4
5pub fn rust_type(
9 ty: &ResolvedType,
10 registry: &TypeRegistry,
11 needs_box: &HashSet<(TypeId, usize)>,
12 context: Option<(TypeId, usize)>,
13) -> String {
14 match ty {
15 ResolvedType::Primitive(p) => primitive_type(p).to_string(),
16 ResolvedType::SubByte(s) => sub_byte_type(s).to_string(),
17 ResolvedType::Semantic(s) => semantic_type(s).to_string(),
18 ResolvedType::Named(id) => {
19 let name = match registry.get(*id) {
20 Some(def) => type_def_name(def),
21 None => "UnresolvedType".to_string(),
22 };
23 if context.is_some_and(|ctx| needs_box.contains(&ctx)) {
24 format!("Box<{name}>")
25 } else {
26 name
27 }
28 }
29 ResolvedType::Optional(inner) => {
30 let inner_str = rust_type(inner, registry, needs_box, context);
31 format!("Option<{inner_str}>")
32 }
33 ResolvedType::Array(inner) => {
34 let inner_str = rust_type(inner, registry, needs_box, None);
35 format!("Vec<{inner_str}>")
36 }
37 ResolvedType::Map(k, v) => {
38 let k_str = rust_type(k, registry, needs_box, None);
39 let v_str = rust_type(v, registry, needs_box, None);
40 format!("BTreeMap<{k_str}, {v_str}>")
41 }
42 ResolvedType::Result(ok, err) => {
43 let ok_str = rust_type(ok, registry, needs_box, context);
44 let err_str = rust_type(err, registry, needs_box, context);
45 format!("Result<{ok_str}, {err_str}>")
46 }
47 _ => "UnknownType".to_string(),
48 }
49}
50
51fn primitive_type(p: &PrimitiveType) -> &'static str {
52 match p {
53 PrimitiveType::Bool => "bool",
54 PrimitiveType::U8 => "u8",
55 PrimitiveType::U16 => "u16",
56 PrimitiveType::U32 => "u32",
57 PrimitiveType::U64 => "u64",
58 PrimitiveType::I8 => "i8",
59 PrimitiveType::I16 => "i16",
60 PrimitiveType::I32 => "i32",
61 PrimitiveType::I64 => "i64",
62 PrimitiveType::F32 => "f32",
63 PrimitiveType::F64 => "f64",
64 PrimitiveType::Void => "()",
65 }
66}
67
68fn sub_byte_type(s: &SubByteType) -> &'static str {
69 if s.signed {
70 "i8"
71 } else {
72 "u8"
73 }
74}
75
76fn semantic_type(s: &SemanticType) -> &'static str {
77 match s {
78 SemanticType::String => "String",
79 SemanticType::Bytes => "Vec<u8>",
80 SemanticType::Rgb => "(u8, u8, u8)",
81 SemanticType::Uuid => "[u8; 16]",
82 SemanticType::Timestamp => "i64",
83 SemanticType::Hash => "[u8; 32]",
84 }
85}
86
87fn type_def_name(def: &TypeDef) -> String {
88 match def {
89 TypeDef::Message(m) => m.name.to_string(),
90 TypeDef::Enum(e) => e.name.to_string(),
91 TypeDef::Flags(f) => f.name.to_string(),
92 TypeDef::Union(u) => u.name.to_string(),
93 TypeDef::Newtype(n) => n.name.to_string(),
94 TypeDef::Config(c) => c.name.to_string(),
95 _ => "UnknownTypeDef".to_string(),
96 }
97}