serde_generate/
swift.rs

1// Copyright (c) Facebook, Inc. and its affiliates
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4#![allow(dead_code)]
5
6use crate::{
7    common,
8    indent::{IndentConfig, IndentedWriter},
9    CodeGeneratorConfig, Encoding,
10};
11use heck::{CamelCase, MixedCase};
12use include_dir::include_dir as include_directory;
13use serde_reflection::{ContainerFormat, Format, FormatHolder, Named, Registry, VariantFormat};
14use std::{
15    collections::{BTreeMap, HashMap},
16    io::{Result, Write},
17    path::PathBuf,
18};
19
20/// Main configuration object for code-generation in Swift.
21pub struct CodeGenerator<'a> {
22    /// Language-independent configuration.
23    config: &'a CodeGeneratorConfig,
24    /// Mapping from external type names to fully-qualified class names (e.g. "MyClass" -> "com.my_org.my_package.MyClass").
25    /// Derived from `config.external_definitions`.
26    external_qualified_names: HashMap<String, String>,
27}
28
29/// Shared state for the code generation of a Swift source file.
30struct SwiftEmitter<'a, T> {
31    /// Writer.
32    out: IndentedWriter<T>,
33    /// Generator.
34    generator: &'a CodeGenerator<'a>,
35    /// Current namespace (e.g. vec!["Package", "MyClass"])
36    current_namespace: Vec<String>,
37}
38
39impl<'a> CodeGenerator<'a> {
40    /// Create a Swift code generator for the given config.
41    pub fn new(config: &'a CodeGeneratorConfig) -> Self {
42        if config.c_style_enums {
43            panic!("Swift does not support generating c-style enums");
44        }
45        let mut external_qualified_names = HashMap::new();
46        for (namespace, names) in &config.external_definitions {
47            let package_name = {
48                let path = namespace.rsplitn(2, '/').collect::<Vec<_>>();
49                if path.len() <= 1 {
50                    namespace
51                } else {
52                    path[0]
53                }
54            };
55            for name in names {
56                external_qualified_names
57                    .insert(name.to_string(), format!("{}.{}", package_name, name));
58            }
59        }
60        Self {
61            config,
62            external_qualified_names,
63        }
64    }
65
66    /// Output class definitions for `registry`.
67    pub fn output(&self, out: &mut dyn Write, registry: &Registry) -> Result<()> {
68        let current_namespace = self
69            .config
70            .module_name
71            .split('.')
72            .map(String::from)
73            .collect::<Vec<_>>();
74
75        let mut emitter = SwiftEmitter {
76            out: IndentedWriter::new(out, IndentConfig::Space(4)),
77            generator: self,
78            current_namespace,
79        };
80
81        emitter.output_preamble()?;
82
83        for (name, format) in registry {
84            emitter.output_container(name, format)?;
85        }
86
87        if self.config.serialization {
88            writeln!(emitter.out)?;
89            emitter.output_trait_helpers(registry)?;
90        }
91
92        Ok(())
93    }
94}
95
96impl<'a, T> SwiftEmitter<'a, T>
97where
98    T: Write,
99{
100    fn output_preamble(&mut self) -> Result<()> {
101        writeln!(self.out, "import Serde\n")?;
102        Ok(())
103    }
104
105    /// Compute a reference to the registry type `name`.
106    fn quote_qualified_name(&self, name: &str) -> String {
107        self.generator
108            .external_qualified_names
109            .get(name)
110            .cloned()
111            .unwrap_or_else(|| format!("{}.{}", self.generator.config.module_name, name))
112    }
113
114    fn output_comment(&mut self, name: &str) -> std::io::Result<()> {
115        let mut path = self.current_namespace.clone();
116        path.push(name.to_string());
117        if let Some(doc) = self.generator.config.comments.get(&path) {
118            let text = textwrap::indent(doc, "// ").replace("\n\n", "\n//\n");
119            write!(self.out, "{}", text)?;
120        }
121        Ok(())
122    }
123
124    fn output_custom_code(&mut self, name: &str) -> std::io::Result<()> {
125        let mut path = self.current_namespace.clone();
126        path.push(name.to_string());
127        if let Some(code) = self.generator.config.custom_code.get(&path) {
128            writeln!(self.out, "\n{}", code)?;
129        }
130        Ok(())
131    }
132
133    fn quote_type(&self, format: &Format) -> String {
134        use Format::*;
135        match format {
136            TypeName(x) => self.quote_qualified_name(x),
137            Unit => "Unit".into(),
138            Bool => "Bool".into(),
139            I8 => "Int8".into(),
140            I16 => "Int16".into(),
141            I32 => "Int32".into(),
142            I64 => "Int64".into(),
143            I128 => "Int128".into(),
144            U8 => "UInt8".into(),
145            U16 => "UInt16".into(),
146            U32 => "UInt32".into(),
147            U64 => "UInt64".into(),
148            U128 => "UInt128".into(),
149            F32 => "Float".into(),
150            F64 => "Double".into(),
151            Char => "Character".into(),
152            Str => "String".into(),
153            Bytes => "[UInt8]".into(),
154
155            Option(format) => format!("{}?", self.quote_type(format)),
156            Seq(format) => format!("[{}]", self.quote_type(format)),
157            Map { key, value } => {
158                format!("[{}: {}]", self.quote_type(key), self.quote_type(value))
159            }
160            // Sadly, Swift tuples are not hashable.
161            Tuple(formats) => format!("Tuple{}<{}>", formats.len(), self.quote_types(formats)),
162            TupleArray { content, size: _ } => {
163                // Sadly, there are no fixed-size arrays in Swift.
164                format!("[{}]", self.quote_type(content))
165            }
166
167            Variable(_) => panic!("unexpected value"),
168        }
169    }
170
171    fn quote_types<'b, I>(&'b self, formats: I) -> String
172    where
173        I: IntoIterator<Item = &'b Format>,
174    {
175        formats
176            .into_iter()
177            .map(|format| self.quote_type(format))
178            .collect::<Vec<_>>()
179            .join(", ")
180    }
181
182    fn enter_class(&mut self, name: &str) {
183        self.out.indent();
184        self.current_namespace.push(name.to_string());
185    }
186
187    fn leave_class(&mut self) {
188        self.out.unindent();
189        self.current_namespace.pop();
190    }
191
192    fn output_trait_helpers(&mut self, registry: &Registry) -> Result<()> {
193        let mut subtypes = BTreeMap::new();
194        for format in registry.values() {
195            format
196                .visit(&mut |f| {
197                    if Self::needs_helper(f) {
198                        subtypes.insert(common::mangle_type(f), f.clone());
199                    }
200                    Ok(())
201                })
202                .unwrap();
203        }
204        for (mangled_name, subtype) in &subtypes {
205            self.output_serialization_helper(mangled_name, subtype)?;
206            self.output_deserialization_helper(mangled_name, subtype)?;
207        }
208        Ok(())
209    }
210
211    fn needs_helper(format: &Format) -> bool {
212        use Format::*;
213        matches!(
214            format,
215            Option(_) | Seq(_) | Map { .. } | Tuple(_) | TupleArray { .. }
216        )
217    }
218
219    fn quote_serialize_value(&self, value: &str, format: &Format) -> String {
220        use Format::*;
221        match format {
222            TypeName(_) => format!("try {}.serialize(serializer: serializer)", value),
223            Unit => format!("try serializer.serialize_unit(value: {})", value),
224            Bool => format!("try serializer.serialize_bool(value: {})", value),
225            I8 => format!("try serializer.serialize_i8(value: {})", value),
226            I16 => format!("try serializer.serialize_i16(value: {})", value),
227            I32 => format!("try serializer.serialize_i32(value: {})", value),
228            I64 => format!("try serializer.serialize_i64(value: {})", value),
229            I128 => format!("try serializer.serialize_i128(value: {})", value),
230            U8 => format!("try serializer.serialize_u8(value: {})", value),
231            U16 => format!("try serializer.serialize_u16(value: {})", value),
232            U32 => format!("try serializer.serialize_u32(value: {})", value),
233            U64 => format!("try serializer.serialize_u64(value: {})", value),
234            U128 => format!("try serializer.serialize_u128(value: {})", value),
235            F32 => format!("try serializer.serialize_f32(value: {})", value),
236            F64 => format!("try serializer.serialize_f64(value: {})", value),
237            Char => format!("try serializer.serialize_char(value: {})", value),
238            Str => format!("try serializer.serialize_str(value: {})", value),
239            Bytes => format!("try serializer.serialize_bytes(value: {})", value),
240            _ => format!(
241                "try serialize_{}(value: {}, serializer: serializer)",
242                common::mangle_type(format),
243                value
244            ),
245        }
246    }
247
248    fn quote_deserialize(&self, format: &Format) -> String {
249        use Format::*;
250        match format {
251            TypeName(name) => format!(
252                "try {}.deserialize(deserializer: deserializer)",
253                self.quote_qualified_name(name)
254            ),
255            Unit => "try deserializer.deserialize_unit()".to_string(),
256            Bool => "try deserializer.deserialize_bool()".to_string(),
257            I8 => "try deserializer.deserialize_i8()".to_string(),
258            I16 => "try deserializer.deserialize_i16()".to_string(),
259            I32 => "try deserializer.deserialize_i32()".to_string(),
260            I64 => "try deserializer.deserialize_i64()".to_string(),
261            I128 => "try deserializer.deserialize_i128()".to_string(),
262            U8 => "try deserializer.deserialize_u8()".to_string(),
263            U16 => "try deserializer.deserialize_u16()".to_string(),
264            U32 => "try deserializer.deserialize_u32()".to_string(),
265            U64 => "try deserializer.deserialize_u64()".to_string(),
266            U128 => "try deserializer.deserialize_u128()".to_string(),
267            F32 => "try deserializer.deserialize_f32()".to_string(),
268            F64 => "try deserializer.deserialize_f64()".to_string(),
269            Char => "try deserializer.deserialize_char()".to_string(),
270            Str => "try deserializer.deserialize_str()".to_string(),
271            Bytes => "try deserializer.deserialize_bytes()".to_string(),
272            _ => format!(
273                "try deserialize_{}(deserializer: deserializer)",
274                common::mangle_type(format)
275            ),
276        }
277    }
278
279    // TODO: Should this be an extension for Serializer?
280    fn output_serialization_helper(&mut self, name: &str, format0: &Format) -> Result<()> {
281        use Format::*;
282
283        write!(
284            self.out,
285            "func serialize_{}<S: Serializer>(value: {}, serializer: S) throws {{",
286            name,
287            self.quote_type(format0)
288        )?;
289        self.out.indent();
290        match format0 {
291            Option(format) => {
292                write!(
293                    self.out,
294                    r#"
295if let value = value {{
296    try serializer.serialize_option_tag(value: true)
297    {}
298}} else {{
299    try serializer.serialize_option_tag(value: false)
300}}
301"#,
302                    self.quote_serialize_value("value", format)
303                )?;
304            }
305
306            Seq(format) => {
307                write!(
308                    self.out,
309                    r#"
310try serializer.serialize_len(value: value.count)
311for item in value {{
312    {}
313}}
314"#,
315                    self.quote_serialize_value("item", format)
316                )?;
317            }
318
319            Map { key, value } => {
320                write!(
321                    self.out,
322                    r#"
323try serializer.serialize_len(value: value.count)
324var offsets : [Int]  = []
325for (key, value) in value {{
326    offsets.append(serializer.get_buffer_offset())
327    {}
328    {}
329}}
330serializer.sort_map_entries(offsets: offsets)
331"#,
332                    self.quote_serialize_value("key", key),
333                    self.quote_serialize_value("value", value)
334                )?;
335            }
336
337            Tuple(formats) => {
338                writeln!(self.out)?;
339                for (index, format) in formats.iter().enumerate() {
340                    let expr = format!("value.field{}", index);
341                    writeln!(self.out, "{}", self.quote_serialize_value(&expr, format))?;
342                }
343            }
344
345            TupleArray { content, size: _ } => {
346                write!(
347                    self.out,
348                    r#"
349for item in value {{
350    {}
351}}
352"#,
353                    self.quote_serialize_value("item", content),
354                )?;
355            }
356
357            _ => panic!("unexpected case"),
358        }
359        self.out.unindent();
360        writeln!(self.out, "}}\n")
361    }
362
363    fn output_deserialization_helper(&mut self, name: &str, format0: &Format) -> Result<()> {
364        use Format::*;
365
366        write!(
367            self.out,
368            "func deserialize_{}<D: Deserializer>(deserializer: D) throws -> {} {{",
369            name,
370            self.quote_type(format0),
371        )?;
372        self.out.indent();
373        match format0 {
374            Option(format) => {
375                write!(
376                    self.out,
377                    r#"
378let tag = try deserializer.deserialize_option_tag()
379if tag {{
380    return {}
381}} else {{
382    return nil
383}}
384"#,
385                    self.quote_deserialize(format),
386                )?;
387            }
388
389            Seq(format) => {
390                write!(
391                    self.out,
392                    r#"
393let length = try deserializer.deserialize_len()
394var obj : [{}] = []
395for _ in 0..<length {{
396    obj.append({})
397}}
398return obj
399"#,
400                    self.quote_type(format),
401                    self.quote_deserialize(format)
402                )?;
403            }
404
405            Map { key, value } => {
406                write!(
407                    self.out,
408                    r#"
409let length = try deserializer.deserialize_len()
410var obj : [{0}: {1}] = [:]
411var previous_slice = Slice(start: 0, end: 0)
412for i in 0..<length {{
413    var slice = Slice(start: 0, end: 0)
414    slice.start = deserializer.get_buffer_offset()
415    let key = {2}
416    slice.end = deserializer.get_buffer_offset()
417    if i > 0 {{
418        try deserializer.check_that_key_slices_are_increasing(key1: previous_slice, key2: slice)
419    }}
420    previous_slice = slice
421    obj[key] = {3}
422}}
423return obj
424"#,
425                    self.quote_type(key),
426                    self.quote_type(value),
427                    self.quote_deserialize(key),
428                    self.quote_deserialize(value),
429                )?;
430            }
431
432            Tuple(formats) => {
433                write!(
434                    self.out,
435                    r#"
436return Tuple{}.init({})
437"#,
438                    formats.len(),
439                    formats
440                        .iter()
441                        .map(|f| self.quote_deserialize(f))
442                        .collect::<Vec<_>>()
443                        .join(", ")
444                )?;
445            }
446
447            TupleArray { content, size } => {
448                write!(
449                    self.out,
450                    r#"
451var obj : [{}] = []
452for _ in 0..<{} {{
453    obj.append({})
454}}
455return obj
456"#,
457                    self.quote_type(content),
458                    size,
459                    self.quote_deserialize(content)
460                )?;
461            }
462
463            _ => panic!("unexpected case"),
464        }
465        self.out.unindent();
466        writeln!(self.out, "}}\n")
467    }
468
469    fn output_variant(&mut self, name: &str, variant: &VariantFormat) -> Result<()> {
470        use VariantFormat::*;
471        self.output_comment(name)?;
472        let name = common::lowercase_first_letter(name).to_mixed_case();
473        match variant {
474            Unit => {
475                writeln!(self.out, "case {}", name)?;
476            }
477            NewType(format) => {
478                writeln!(self.out, "case {}({})", name, self.quote_type(format))?;
479            }
480            Tuple(formats) => {
481                if formats.is_empty() {
482                    writeln!(self.out, "case {}", name)?;
483                } else {
484                    writeln!(self.out, "case {}({})", name, self.quote_types(formats))?;
485                }
486            }
487            Struct(fields) => {
488                if fields.is_empty() {
489                    writeln!(self.out, "case {}", name)?;
490                } else {
491                    writeln!(
492                        self.out,
493                        "case {}({})",
494                        name,
495                        fields
496                            .iter()
497                            .map(|f| format!("{}: {}", f.name, self.quote_type(&f.value)))
498                            .collect::<Vec<_>>()
499                            .join(", ")
500                    )?;
501                }
502            }
503            Variable(_) => panic!("incorrect value"),
504        }
505        Ok(())
506    }
507
508    fn variant_fields(variant: &VariantFormat) -> Vec<Named<Format>> {
509        use VariantFormat::*;
510        match variant {
511            Unit => Vec::new(),
512            NewType(format) => vec![Named {
513                name: "x".to_string(),
514                value: format.as_ref().clone(),
515            }],
516            Tuple(formats) => formats
517                .clone()
518                .into_iter()
519                .enumerate()
520                .map(|(i, f)| Named {
521                    name: format!("x{}", i),
522                    value: f,
523                })
524                .collect(),
525            Struct(fields) => fields.clone(),
526            Variable(_) => panic!("incorrect value"),
527        }
528    }
529
530    fn output_struct_container(&mut self, name: &str, fields: &[Named<Format>]) -> Result<()> {
531        // Struct
532        writeln!(self.out)?;
533        self.output_comment(name)?;
534        writeln!(self.out, "public struct {}: Hashable {{", name)?;
535        self.enter_class(name);
536        for field in fields {
537            self.output_comment(&field.name)?;
538            writeln!(
539                self.out,
540                "@Indirect public var {}: {}",
541                field.name,
542                self.quote_type(&field.value)
543            )?;
544        }
545        // Public constructor
546        writeln!(
547            self.out,
548            "\npublic init({}) {{",
549            fields
550                .iter()
551                .map(|f| format!("{}: {}", &f.name, self.quote_type(&f.value)))
552                .collect::<Vec<_>>()
553                .join(", ")
554        )?;
555        self.out.indent();
556        for field in fields {
557            writeln!(self.out, "self.{0} = {0}", &field.name)?;
558        }
559        self.out.unindent();
560        writeln!(self.out, "}}")?;
561        // Serialize
562        if self.generator.config.serialization {
563            writeln!(
564                self.out,
565                "\npublic func serialize<S: Serializer>(serializer: S) throws {{",
566            )?;
567            self.out.indent();
568            writeln!(self.out, "try serializer.increase_container_depth()")?;
569            for field in fields {
570                writeln!(
571                    self.out,
572                    "{}",
573                    self.quote_serialize_value(&format!("self.{}", &field.name), &field.value)
574                )?;
575            }
576            writeln!(self.out, "try serializer.decrease_container_depth()")?;
577            self.out.unindent();
578            writeln!(self.out, "}}")?;
579
580            for encoding in &self.generator.config.encodings {
581                self.output_struct_serialize_for_encoding(*encoding)?;
582            }
583        }
584        // Deserialize
585        if self.generator.config.serialization {
586            writeln!(
587                self.out,
588                "\npublic static func deserialize<D: Deserializer>(deserializer: D) throws -> {} {{",
589                name,
590            )?;
591            self.out.indent();
592            writeln!(self.out, "try deserializer.increase_container_depth()")?;
593            for field in fields {
594                writeln!(
595                    self.out,
596                    "let {} = {}",
597                    field.name,
598                    self.quote_deserialize(&field.value)
599                )?;
600            }
601            writeln!(self.out, "try deserializer.decrease_container_depth()")?;
602            writeln!(
603                self.out,
604                "return {}.init({})",
605                name,
606                fields
607                    .iter()
608                    .map(|f| format!("{0}: {0}", &f.name))
609                    .collect::<Vec<_>>()
610                    .join(", ")
611            )?;
612            self.out.unindent();
613            writeln!(self.out, "}}")?;
614
615            for encoding in &self.generator.config.encodings {
616                self.output_struct_deserialize_for_encoding(name, *encoding)?;
617            }
618        }
619        // Custom code
620        self.output_custom_code(name)?;
621        self.leave_class();
622        writeln!(self.out, "}}")?;
623        Ok(())
624    }
625
626    fn output_struct_serialize_for_encoding(&mut self, encoding: Encoding) -> Result<()> {
627        writeln!(
628            self.out,
629            r#"
630public func {0}Serialize() throws -> [UInt8] {{
631    let serializer = {1}Serializer.init();
632    try self.serialize(serializer: serializer)
633    return serializer.get_bytes()
634}}"#,
635            encoding.name(),
636            encoding.name().to_camel_case()
637        )
638    }
639
640    fn output_struct_deserialize_for_encoding(
641        &mut self,
642        name: &str,
643        encoding: Encoding,
644    ) -> Result<()> {
645        writeln!(
646            self.out,
647            r#"
648public static func {1}Deserialize(input: [UInt8]) throws -> {0} {{
649    let deserializer = {2}Deserializer.init(input: input);
650    let obj = try deserialize(deserializer: deserializer)
651    if deserializer.get_buffer_offset() < input.count {{
652        throw DeserializationError.invalidInput(issue: "Some input bytes were not read")
653    }}
654    return obj
655}}"#,
656            name,
657            encoding.name(),
658            encoding.name().to_camel_case(),
659        )
660    }
661
662    fn output_enum_container(
663        &mut self,
664        name: &str,
665        variants: &BTreeMap<u32, Named<VariantFormat>>,
666    ) -> Result<()> {
667        writeln!(self.out)?;
668        self.output_comment(name)?;
669        writeln!(self.out, "indirect public enum {}: Hashable {{", name)?;
670        self.current_namespace.push(name.to_string());
671        self.out.indent();
672        for variant in variants.values() {
673            self.output_variant(&variant.name, &variant.value)?;
674        }
675
676        // Serialize
677        if self.generator.config.serialization {
678            writeln!(
679                self.out,
680                "\npublic func serialize<S: Serializer>(serializer: S) throws {{",
681            )?;
682            self.out.indent();
683            writeln!(self.out, "try serializer.increase_container_depth()")?;
684            writeln!(self.out, "switch self {{")?;
685            for (index, variant) in variants {
686                let fields = Self::variant_fields(&variant.value);
687                let formatted_variant_name =
688                    common::lowercase_first_letter(&variant.name).to_mixed_case();
689                if fields.is_empty() {
690                    writeln!(self.out, "case .{}:", formatted_variant_name)?;
691                } else {
692                    writeln!(
693                        self.out,
694                        "case .{}({}):",
695                        formatted_variant_name,
696                        fields
697                            .iter()
698                            .map(|f| format!("let {}", f.name))
699                            .collect::<Vec<_>>()
700                            .join(", ")
701                    )?;
702                }
703                self.out.indent();
704                writeln!(
705                    self.out,
706                    "try serializer.serialize_variant_index(value: {})",
707                    index
708                )?;
709                for field in fields {
710                    writeln!(
711                        self.out,
712                        "{}",
713                        self.quote_serialize_value(&field.name, &field.value)
714                    )?;
715                }
716                self.out.unindent();
717            }
718            writeln!(self.out, "}}")?;
719            writeln!(self.out, "try serializer.decrease_container_depth()")?;
720            self.out.unindent();
721            writeln!(self.out, "}}")?;
722
723            for encoding in &self.generator.config.encodings {
724                self.output_struct_serialize_for_encoding(*encoding)?;
725            }
726        }
727        // Deserialize
728        if self.generator.config.serialization {
729            write!(
730                self.out,
731                "\npublic static func deserialize<D: Deserializer>(deserializer: D) throws -> {0} {{",
732                name
733            )?;
734            self.out.indent();
735            writeln!(
736                self.out,
737                r#"
738let index = try deserializer.deserialize_variant_index()
739try deserializer.increase_container_depth()
740switch index {{"#,
741            )?;
742            for (index, variant) in variants {
743                writeln!(self.out, "case {}:", index)?;
744                self.out.indent();
745                let formatted_variant_name =
746                    common::lowercase_first_letter(&variant.name).to_mixed_case();
747                let fields = Self::variant_fields(&variant.value);
748                if fields.is_empty() {
749                    writeln!(self.out, "try deserializer.decrease_container_depth()")?;
750                    writeln!(self.out, "return .{}", formatted_variant_name)?;
751                    self.out.unindent();
752                    continue;
753                }
754                for field in &fields {
755                    writeln!(
756                        self.out,
757                        "let {} = {}",
758                        field.name,
759                        self.quote_deserialize(&field.value)
760                    )?;
761                }
762                writeln!(self.out, "try deserializer.decrease_container_depth()")?;
763                let init_values = match &variant.value {
764                    VariantFormat::Struct(_) => fields
765                        .iter()
766                        .map(|f| format!("{0}: {0}", f.name))
767                        .collect::<Vec<_>>()
768                        .join(", "),
769                    _ => fields
770                        .iter()
771                        .map(|f| f.name.to_string())
772                        .collect::<Vec<_>>()
773                        .join(", "),
774                };
775                writeln!(
776                    self.out,
777                    "return .{}({})",
778                    formatted_variant_name, init_values
779                )?;
780                self.out.unindent();
781            }
782            writeln!(
783                self.out,
784                "default: throw DeserializationError.invalidInput(issue: \"Unknown variant index for {}: \\(index)\")",
785                name,
786            )?;
787            writeln!(self.out, "}}")?;
788            self.out.unindent();
789            writeln!(self.out, "}}")?;
790
791            for encoding in &self.generator.config.encodings {
792                self.output_struct_deserialize_for_encoding(name, *encoding)?;
793            }
794        }
795
796        self.current_namespace.pop();
797        // Custom code
798        self.output_custom_code(name)?;
799        self.out.unindent();
800        writeln!(self.out, "}}")?;
801        Ok(())
802    }
803
804    fn output_container(&mut self, name: &str, format: &ContainerFormat) -> Result<()> {
805        use ContainerFormat::*;
806        let fields = match format {
807            UnitStruct => Vec::new(),
808            NewTypeStruct(format) => vec![Named {
809                name: "value".to_string(),
810                value: format.as_ref().clone(),
811            }],
812            TupleStruct(formats) => formats
813                .iter()
814                .enumerate()
815                .map(|(i, f)| Named {
816                    name: format!("field{}", i),
817                    value: f.clone(),
818                })
819                .collect(),
820            Struct(fields) => fields
821                .iter()
822                .map(|f| Named {
823                    name: f.name.to_mixed_case(),
824                    value: f.value.clone(),
825                })
826                .collect(),
827            Enum(variants) => {
828                self.output_enum_container(name, variants)?;
829                return Ok(());
830            }
831        };
832        self.output_struct_container(name, &fields)
833    }
834}
835
836/// Installer for generated source files in Swift.
837pub struct Installer {
838    install_dir: PathBuf,
839}
840
841impl Installer {
842    pub fn new(install_dir: PathBuf) -> Self {
843        Installer { install_dir }
844    }
845
846    fn install_runtime(
847        &self,
848        source_dir: include_dir::Dir,
849        path: &str,
850    ) -> std::result::Result<(), Box<dyn std::error::Error>> {
851        let dir_path = self.install_dir.join(path);
852        std::fs::create_dir_all(&dir_path)?;
853        for entry in source_dir.files() {
854            let mut file = std::fs::File::create(dir_path.join(entry.path()))?;
855            file.write_all(entry.contents())?;
856        }
857        Ok(())
858    }
859}
860
861impl crate::SourceInstaller for Installer {
862    type Error = Box<dyn std::error::Error>;
863
864    fn install_module(
865        &self,
866        config: &CodeGeneratorConfig,
867        registry: &Registry,
868    ) -> std::result::Result<(), Self::Error> {
869        let dir_path = self.install_dir.join("Sources").join(&config.module_name);
870        std::fs::create_dir_all(&dir_path)?;
871        let source_path = dir_path.join(format!("{}.swift", config.module_name.to_camel_case()));
872        let mut file = std::fs::File::create(source_path)?;
873        let generator = CodeGenerator::new(config);
874        generator.output(&mut file, registry)?;
875        Ok(())
876    }
877
878    fn install_serde_runtime(&self) -> std::result::Result<(), Self::Error> {
879        self.install_runtime(
880            include_directory!("runtime/swift/Sources/Serde"),
881            "Sources/Serde",
882        )
883    }
884
885    fn install_bincode_runtime(&self) -> std::result::Result<(), Self::Error> {
886        // Ignored. Currently always installed with Serde.
887        Ok(())
888    }
889
890    fn install_bcs_runtime(&self) -> std::result::Result<(), Self::Error> {
891        // Ignored. Currently always installed with Serde.
892        Ok(())
893    }
894}