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/. */
4use heck::{CamelCase, MixedCase};
5use std::fmt::Display;
67/// Get the idiomatic Swift rendering of a class name (for enums, records, errors, etc).
8pub fn class_name(nm: &dyn Display) -> String {
9 nm.to_string().to_camel_case()
10}
1112/// Get the idiomatic Swift rendering of a variable name.
13pub fn var_name(nm: &dyn Display) -> String {
14 nm.to_string().to_mixed_case()
15}
1617/// Get the idiomatic Swift rendering of an individual enum variant.
18pub fn enum_variant_name(nm: &dyn Display) -> String {
19 nm.to_string().to_mixed_case()
20}
2122/// Surrounds a property name with quotes. It is assumed that property names do not need escaping.
23pub fn quoted(v: &dyn Display) -> String {
24format!(r#""{}""#, v)
25}
2627pub(crate) mod code_type {
28use std::fmt::Display;
2930use crate::backends::{CodeOracle, CodeType};
3132/// The language specific expression that gets a value of the `prop` from the `vars` object.
33pub(crate) fn property_getter(
34 ct: &dyn CodeType,
35 oracle: &dyn CodeOracle,
36 vars: &dyn Display,
37 prop: &dyn Display,
38 default: &dyn Display,
39 ) -> String {
40let getter = ct.value_getter(oracle, vars, prop);
41let mapper = ct.value_mapper(oracle);
42let default = ct
43 .defaults_mapper(oracle, &default, vars)
44 .unwrap_or_else(|| default.to_string());
45let merger = ct.value_merger(oracle, &default);
4647// We need to be quite careful about option chaining.
48 // Swift takes the `?` as an indicator to _stop evaluating the chain expression_ if the immediately preceeding
49 // expression returns an optional.
50 // Only the value_getter returns an optional, so that's all we need to `?`.
51 // https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html
52let getter = match (mapper, merger) {
53 (Some(mapper), Some(merger)) => format!("{}?.{}.{}", getter, mapper, merger),
54 (Some(mapper), None) => format!("{}?.{}", getter, mapper),
55 (None, Some(merger)) => format!("{}?.{}", getter, merger),
56 (None, None) => getter,
57 };
5859format!(
60"{getter} ?? {fallback}",
61 getter = getter,
62 fallback = default,
63 )
64 }
6566pub(crate) fn value_getter(
67 ct: &dyn CodeType,
68 oracle: &dyn CodeOracle,
69 vars: &dyn Display,
70 prop: &dyn Display,
71 ) -> String {
72let vt = ct.variables_type(oracle);
73format!(
74"{vars}.get{vt}(\"{prop}\")",
75 vars = vars,
76 vt = vt,
77 prop = prop
78 )
79 }
8081pub(crate) fn value_mapper(ct: &dyn CodeType, oracle: &dyn CodeOracle) -> Option<String> {
82let transform = ct.create_transform(oracle)?;
83Some(format!("map({})", transform))
84 }
85}