1#![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
20pub struct CodeGenerator<'a> {
22 config: &'a CodeGeneratorConfig,
24 external_qualified_names: HashMap<String, String>,
27}
28
29struct SwiftEmitter<'a, T> {
31 out: IndentedWriter<T>,
33 generator: &'a CodeGenerator<'a>,
35 current_namespace: Vec<String>,
37}
38
39impl<'a> CodeGenerator<'a> {
40 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 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 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 Tuple(formats) => format!("Tuple{}<{}>", formats.len(), self.quote_types(formats)),
162 TupleArray { content, size: _ } => {
163 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 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 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 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 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 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 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 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 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 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
836pub 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 Ok(())
888 }
889
890 fn install_bcs_runtime(&self) -> std::result::Result<(), Self::Error> {
891 Ok(())
893 }
894}