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/. */
45use std::fmt::Display;
67use super::common::{code_type, quoted};
8use crate::backends::{CodeOracle, CodeType, LiteralRenderer, TypeIdentifier, VariablesType};
9use crate::intermediate_representation::Literal;
1011pub(crate) struct TextCodeType;
1213impl CodeType for TextCodeType {
14/// The language specific label used to reference this type. This will be used in
15 /// method signatures and property declarations.
16fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
17"String".into()
18 }
1920fn 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 }
2930fn 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 }
3839fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
40 code_type::value_mapper(self, oracle)
41 }
4243/// 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.
45fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
46 VariablesType::Text
47 }
4849/// A representation of the given literal for this type.
50 /// N.B. `Literal` is aliased from `serde_json::Value`.
51fn literal(
52&self,
53 _oracle: &dyn CodeOracle,
54 _ctx: &dyn Display,
55 _renderer: &dyn LiteralRenderer,
56 literal: &Literal,
57 ) -> String {
58match literal {
59 serde_json::Value::String(v) => quoted(v),
60_ => unreachable!("Expecting a string"),
61 }
62 }
6364fn defaults_type(&self, oracle: &dyn CodeOracle) -> String {
65 oracle.find(&TypeIdentifier::String).type_label(oracle)
66 }
6768fn defaults_mapper(
69&self,
70 _oracle: &dyn CodeOracle,
71 value: &dyn Display,
72 vars: &dyn Display,
73 ) -> Option<String> {
74Some(format!(
75"{vars}.resourceBundles.getString(named: {value}) ?? {value}",
76 vars = vars,
77 value = value
78 ))
79 }
80}
8182pub(crate) struct ImageCodeType;
8384impl CodeType for ImageCodeType {
85/// The language specific label used to reference this type. This will be used in
86 /// method signatures and property declarations.
87fn type_label(&self, _oracle: &dyn CodeOracle) -> String {
88"UIImage".into()
89 }
9091fn 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 }
100101fn 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 }
109110fn value_mapper(&self, oracle: &dyn CodeOracle) -> Option<String> {
111 code_type::value_mapper(self, oracle)
112 }
113114/// 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.
116fn variables_type(&self, _oracle: &dyn CodeOracle) -> VariablesType {
117 VariablesType::Image
118 }
119120fn as_json_transform(&self, _oracle: &dyn CodeOracle, prop: &dyn Display) -> Option<String> {
121Some(format!("{prop}.encodableImageName"))
122 }
123124/// A representation of the given literal for this type.
125 /// N.B. `Literal` is aliased from `serde_json::Value`.
126fn literal(
127&self,
128 _oracle: &dyn CodeOracle,
129 _ctx: &dyn Display,
130 _renderer: &dyn LiteralRenderer,
131 literal: &Literal,
132 ) -> String {
133match literal {
134 serde_json::Value::String(v) => quoted(v),
135_ => unreachable!("Expecting a string matching an image/drawable resource"),
136 }
137 }
138139fn defaults_type(&self, oracle: &dyn CodeOracle) -> String {
140 oracle.find(&TypeIdentifier::String).type_label(oracle)
141 }
142143fn defaults_mapper(
144&self,
145 _oracle: &dyn CodeOracle,
146 value: &dyn Display,
147 vars: &dyn Display,
148 ) -> Option<String> {
149Some(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 }
162163fn imports(&self, _oracle: &dyn CodeOracle) -> Option<Vec<String>> {
164Some(vec!["UIKit".to_string()])
165 }
166}