nimbus_fml/backends/swift/gen_structs/
bundled.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use std::fmt::Display;
6
7use super::common::{code_type, quoted};
8use crate::backends::{CodeOracle, CodeType, LiteralRenderer, TypeIdentifier, VariablesType};
9use crate::intermediate_representation::Literal;
10
11pub(crate) struct TextCodeType;
12
13impl CodeType for TextCodeType {
14    /// The language specific label used to reference this type. This will be used in
15    /// method signatures and property declarations.
16    fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
17        "String".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    /// The name of the type as it's represented in the `Variables` object.
44    /// The string return may be used to combine with an identifier, e.g. a `Variables` method name.
45    fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
46        VariablesType::Text
47    }
48
49    /// A representation of the given literal for this type.
50    /// N.B. `Literal` is aliased from `serde_json::Value`.
51    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::String(v) => quoted(v),
60            _ => unreachable!("Expecting a string"),
61        }
62    }
63
64    fn defaults_type(&self, oracle: &dyn CodeOracle) -> String {
65        oracle.find(&TypeIdentifier::String).type_label(oracle)
66    }
67
68    fn defaults_mapper(
69        &self,
70        _oracle: &dyn CodeOracle,
71        value: &dyn Display,
72        vars: &dyn Display,
73    ) -> Option<String> {
74        Some(format!(
75            "{vars}.resourceBundles.getString(named: {value}) ?? {value}",
76            vars = vars,
77            value = value
78        ))
79    }
80}
81
82pub(crate) struct ImageCodeType;
83
84impl CodeType for ImageCodeType {
85    /// The language specific label used to reference this type. This will be used in
86    /// method signatures and property declarations.
87    fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
88        "UIImage".into()
89    }
90
91    fn property_getter(
92        &self,
93        oracle: &dyn CodeOracle,
94        vars: &dyn Display,
95        prop: &dyn Display,
96        default: &dyn Display,
97    ) -> String {
98        code_type::property_getter(self, oracle, vars, prop, default)
99    }
100
101    fn value_getter(
102        &self,
103        oracle: &dyn CodeOracle,
104        vars: &dyn Display,
105        prop: &dyn Display,
106    ) -> String {
107        code_type::value_getter(self, oracle, vars, prop)
108    }
109
110    fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
111        code_type::value_mapper(self, oracle)
112    }
113
114    /// The name of the type as it's represented in the `Variables` object.
115    /// The string return may be used to combine with an identifier, e.g. a `Variables` method name.
116    fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
117        VariablesType::Image
118    }
119
120    fn as_json_transform(&self, _oracle: &dyn CodeOracle, prop: &dyn Display) -> Option<String> {
121        Some(format!("{prop}.encodableImageName"))
122    }
123
124    /// A representation of the given literal for this type.
125    /// N.B. `Literal` is aliased from `serde_json::Value`.
126    fn literal(
127        &self,
128        _oracle: &dyn CodeOracle,
129        _ctx: &dyn Display,
130        _renderer: &dyn LiteralRenderer,
131        literal: &Literal,
132    ) -> String {
133        match literal {
134            serde_json::Value::String(v) => quoted(v),
135            _ => unreachable!("Expecting a string matching an image/drawable resource"),
136        }
137    }
138
139    fn defaults_type(&self, oracle: &dyn CodeOracle) -> String {
140        oracle.find(&TypeIdentifier::String).type_label(oracle)
141    }
142
143    fn defaults_mapper(
144        &self,
145        _oracle: &dyn CodeOracle,
146        value: &dyn Display,
147        vars: &dyn Display,
148    ) -> Option<String> {
149        Some(format!(
150            // UIKit does not provide any compile time safety for bundled images. The string name isn't found to be missing
151            // until runtime.
152            // For these fallback images, if they are missing, we consider it a programmer error,
153            // so `getImageNotNull(image:)` fatalErrors if the image doesn't exist.
154            //
155            // The assumption here is that the developer will discover this
156            // early in the cycle, and provide the image or change the name.
157            "{vars}.resourceBundles.getImageNotNull(named: {value})",
158            vars = vars,
159            value = value
160        ))
161    }
162
163    fn imports(&self, _oracle: &dyn CodeOracle) -> Option<Vec<String>> {
164        Some(vec!["UIKit".to_string()])
165    }
166}