nimbus_fml/backends/swift/gen_structs/
primitives.rs
1use std::fmt::Display;
6
7use super::common::{self, code_type};
8use crate::backends::{CodeOracle, CodeType, LiteralRenderer, VariablesType};
9use crate::intermediate_representation::Literal;
10
11pub(crate) struct BooleanCodeType;
12
13impl CodeType for BooleanCodeType {
14 fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
17 "Bool".into()
18 }
19
20 fn property_getter(
21 &self,
22 oracle: &dyn CodeOracle,
23 vars: &dyn Display,
24 prop: &dyn Display,
25 default: &dyn Display,
26 ) -> String {
27 code_type::property_getter(self, oracle, vars, prop, default)
28 }
29
30 fn value_getter(
31 &self,
32 oracle: &dyn CodeOracle,
33 vars: &dyn Display,
34 prop: &dyn Display,
35 ) -> String {
36 code_type::value_getter(self, oracle, vars, prop)
37 }
38
39 fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
40 code_type::value_mapper(self, oracle)
41 }
42
43 fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
46 VariablesType::Bool
47 }
48
49 fn literal(
52 &self,
53 _oracle: &dyn CodeOracle,
54 _ctx: &dyn Display,
55 _renderer: &dyn LiteralRenderer,
56 literal: &Literal,
57 ) -> String {
58 match literal {
59 serde_json::Value::Bool(v) => {
60 if *v {
61 "true".to_string()
62 } else {
63 "false".to_string()
64 }
65 }
66 _ => unreachable!("Expecting a boolean"),
67 }
68 }
69}
70
71pub(crate) struct IntCodeType;
72
73impl CodeType for IntCodeType {
74 fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
77 "Int".into()
78 }
79
80 fn property_getter(
81 &self,
82 oracle: &dyn CodeOracle,
83 vars: &dyn Display,
84 prop: &dyn Display,
85 default: &dyn Display,
86 ) -> String {
87 code_type::property_getter(self, oracle, vars, prop, default)
88 }
89
90 fn value_getter(
91 &self,
92 oracle: &dyn CodeOracle,
93 vars: &dyn Display,
94 prop: &dyn Display,
95 ) -> String {
96 code_type::value_getter(self, oracle, vars, prop)
97 }
98
99 fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
100 code_type::value_mapper(self, oracle)
101 }
102
103 fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
106 VariablesType::Int
107 }
108
109 fn literal(
112 &self,
113 _oracle: &dyn CodeOracle,
114 _ctx: &dyn Display,
115 _renderer: &dyn LiteralRenderer,
116 literal: &Literal,
117 ) -> String {
118 match literal {
119 serde_json::Value::Number(v) => {
120 format!("{:.0}", v)
121 }
122 _ => unreachable!("Expecting a number"),
123 }
124 }
125}
126
127pub(crate) struct StringCodeType;
128
129impl CodeType for StringCodeType {
130 fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
133 "String".into()
134 }
135
136 fn property_getter(
137 &self,
138 oracle: &dyn CodeOracle,
139 vars: &dyn Display,
140 prop: &dyn Display,
141 default: &dyn Display,
142 ) -> String {
143 code_type::property_getter(self, oracle, vars, prop, default)
144 }
145
146 fn value_getter(
147 &self,
148 oracle: &dyn CodeOracle,
149 vars: &dyn Display,
150 prop: &dyn Display,
151 ) -> String {
152 code_type::value_getter(self, oracle, vars, prop)
153 }
154
155 fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
156 code_type::value_mapper(self, oracle)
157 }
158
159 fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
162 VariablesType::String
163 }
164
165 fn literal(
168 &self,
169 _oracle: &dyn CodeOracle,
170 _ctx: &dyn Display,
171 _renderer: &dyn LiteralRenderer,
172 literal: &Literal,
173 ) -> String {
174 match literal {
175 serde_json::Value::String(v) => common::quoted(v),
176 _ => unreachable!("Expecting a string"),
177 }
178 }
179}
180
181#[cfg(test)]
182mod unit_tests {
183
184 use serde_json::json;
185
186 use crate::backends::TypeIdentifier;
187
188 use super::*;
189
190 struct TestCodeOracle;
191 impl CodeOracle for TestCodeOracle {
192 fn find(&self, _type_: &TypeIdentifier) -> Box<dyn CodeType> {
193 unreachable!()
194 }
195 }
196
197 struct TestRenderer;
198 impl LiteralRenderer for TestRenderer {
199 fn literal(
200 &self,
201 _oracle: &dyn CodeOracle,
202 _typ: &TypeIdentifier,
203 _value: &Literal,
204 _ctx: &dyn Display,
205 ) -> String {
206 unreachable!()
207 }
208 }
209
210 fn oracle() -> Box<dyn CodeOracle> {
211 Box::new(TestCodeOracle) as Box<dyn CodeOracle>
212 }
213
214 fn bool_type() -> Box<dyn CodeType> {
215 Box::new(BooleanCodeType) as Box<dyn CodeType>
216 }
217
218 fn string_type() -> Box<dyn CodeType> {
219 Box::new(StringCodeType) as Box<dyn CodeType>
220 }
221
222 fn int_type() -> Box<dyn CodeType> {
223 Box::new(IntCodeType) as Box<dyn CodeType>
224 }
225
226 #[test]
227 fn test_type_label() {
228 let oracle = &*oracle();
229
230 let ct = bool_type();
231 assert_eq!("Bool".to_string(), ct.type_label(oracle));
232
233 let ct = string_type();
234 assert_eq!("String".to_string(), ct.type_label(oracle));
235
236 let ct = int_type();
237 assert_eq!("Int".to_string(), ct.type_label(oracle));
238 }
239
240 #[test]
241 fn test_literal() {
242 let oracle = &*oracle();
243 let finder = &TestRenderer;
244 let ctx = String::from("ctx");
245 let ct = bool_type();
246 assert_eq!(
247 "true".to_string(),
248 ct.literal(oracle, &ctx, finder, &json!(true))
249 );
250 assert_eq!(
251 "false".to_string(),
252 ct.literal(oracle, &ctx, finder, &json!(false))
253 );
254
255 let ct = string_type();
256 assert_eq!(
257 r#""no""#.to_string(),
258 ct.literal(oracle, &ctx, finder, &json!("no"))
259 );
260 assert_eq!(
261 r#""yes""#.to_string(),
262 ct.literal(oracle, &ctx, finder, &json!("yes"))
263 );
264
265 let ct = int_type();
266 assert_eq!("1".to_string(), ct.literal(oracle, &ctx, finder, &json!(1)));
267 assert_eq!("2".to_string(), ct.literal(oracle, &ctx, finder, &json!(2)));
268 }
269
270 #[test]
271 fn test_get_value() {
272 let oracle = &*oracle();
273
274 let ct = bool_type();
275 assert_eq!(
276 r#"v.getBool("the-property")"#.to_string(),
277 ct.value_getter(oracle, &"v", &"the-property")
278 );
279
280 let ct = string_type();
281 assert_eq!(
282 r#"v.getString("the-property")"#.to_string(),
283 ct.value_getter(oracle, &"v", &"the-property")
284 );
285
286 let ct = int_type();
287 assert_eq!(
288 r#"v.getInt("the-property")"#.to_string(),
289 ct.value_getter(oracle, &"v", &"the-property")
290 );
291 }
292}