aleph_syntax_tree/
types.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(tag = "type")]
9pub enum Type {
10 Int,
12 Float,
14 Bool,
16 String,
18 Bytes,
20 #[default]
29 Unit,
30 List { elem: Box<Type> },
32 Tuple { elems: Vec<Type> },
34 Record { fields: Vec<RecordField> },
36 Sum { variants: Vec<Variant> },
38 Fun { params: Vec<Type>, ret: Box<Type> },
40 Var { name: String },
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46pub struct RecordField {
47 pub name: String,
48 pub ty: Type,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct Variant {
54 pub name: String,
55 pub fields: Vec<Type>,
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn primitive_round_trips_through_json() {
64 let ty = Type::Int;
65 let json = serde_json::to_string(&ty).unwrap();
66 let back: Type = serde_json::from_str(&json).unwrap();
67 assert_eq!(ty, back);
68 }
69
70 #[test]
71 fn function_type_round_trips_through_json() {
72 let ty = Type::Fun {
73 params: vec![Type::Int, Type::String],
74 ret: Box::new(Type::Bool),
75 };
76 let json = serde_json::to_string(&ty).unwrap();
77 let back: Type = serde_json::from_str(&json).unwrap();
78 assert_eq!(ty, back);
79 }
80
81 #[test]
82 fn sum_type_round_trips_through_json() {
83 let ty = Type::Sum {
84 variants: vec![
85 Variant { name: "Circle".to_string(), fields: vec![Type::Float] },
86 Variant { name: "Rect".to_string(), fields: vec![Type::Float, Type::Float] },
87 ],
88 };
89 let json = serde_json::to_string(&ty).unwrap();
90 let back: Type = serde_json::from_str(&json).unwrap();
91 assert_eq!(ty, back);
92 }
93
94 #[test]
95 fn struct_like_variant_wire_format_is_locked() {
96 let ty = Type::List { elem: Box::new(Type::Int) };
97 assert_eq!(
98 serde_json::to_string(&ty).unwrap(),
99 r#"{"type":"List","elem":{"type":"Int"}}"#
100 );
101 }
102
103 #[test]
104 fn record_wire_format_is_locked() {
105 let ty = Type::Record {
106 fields: vec![RecordField { name: "x".to_string(), ty: Type::Int }],
107 };
108 assert_eq!(
109 serde_json::to_string(&ty).unwrap(),
110 r#"{"type":"Record","fields":[{"name":"x","ty":{"type":"Int"}}]}"#
111 );
112 }
113
114 #[test]
115 fn var_round_trips_through_json() {
116 let ty = Type::Var { name: "a".to_string() };
117 let json = serde_json::to_string(&ty).unwrap();
118 let back: Type = serde_json::from_str(&json).unwrap();
119 assert_eq!(ty, back);
120 }
121
122 #[test]
123 fn nested_composite_type_round_trips_through_json() {
124 let ty = Type::List {
125 elem: Box::new(Type::Record {
126 fields: vec![RecordField { name: "x".to_string(), ty: Type::Float }],
127 }),
128 };
129 let json = serde_json::to_string(&ty).unwrap();
130 let back: Type = serde_json::from_str(&json).unwrap();
131 assert_eq!(ty, back);
132 }
133}