serde_generate/
config.rs

1// Copyright (c) Facebook, Inc. and its affiliates
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use std::collections::{BTreeMap, BTreeSet};
5
6/// Code generation options meant to be supported by all languages.
7#[derive(Clone, Debug)]
8pub struct CodeGeneratorConfig {
9    pub module_name: String,
10    pub serialization: bool,
11    pub encodings: BTreeSet<Encoding>,
12    pub external_definitions: ExternalDefinitions,
13    pub comments: DocComments,
14    pub custom_code: CustomCode,
15    pub c_style_enums: bool,
16    pub package_manifest: bool,
17}
18
19#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
20pub enum Encoding {
21    Bincode,
22    Bcs,
23}
24
25/// Track types definitions provided by external modules.
26pub type ExternalDefinitions =
27    std::collections::BTreeMap</* module */ String, /* type names */ Vec<String>>;
28
29/// Track documentation to be attached to particular definitions.
30pub type DocComments =
31    std::collections::BTreeMap</* qualified name */ Vec<String>, /* comment */ String>;
32
33/// Track custom code to be added to particular definitions (use with care!).
34pub type CustomCode = std::collections::BTreeMap<
35    /* qualified name */ Vec<String>,
36    /* custom code */ String,
37>;
38
39/// How to copy generated source code and available runtimes for a given language.
40pub trait SourceInstaller {
41    type Error;
42
43    /// Create a module exposing the container types contained in the registry.
44    fn install_module(
45        &self,
46        config: &CodeGeneratorConfig,
47        registry: &serde_reflection::Registry,
48    ) -> std::result::Result<(), Self::Error>;
49
50    /// Install the serde runtime.
51    fn install_serde_runtime(&self) -> std::result::Result<(), Self::Error>;
52
53    /// Install the bincode runtime.
54    fn install_bincode_runtime(&self) -> std::result::Result<(), Self::Error>;
55
56    /// Install the Libra Canonical Serialization (BCS) runtime.
57    fn install_bcs_runtime(&self) -> std::result::Result<(), Self::Error>;
58}
59
60impl CodeGeneratorConfig {
61    /// Default config for the given module name.
62    pub fn new(module_name: String) -> Self {
63        Self {
64            module_name,
65            serialization: true,
66            encodings: BTreeSet::new(),
67            external_definitions: BTreeMap::new(),
68            comments: BTreeMap::new(),
69            custom_code: BTreeMap::new(),
70            c_style_enums: false,
71            package_manifest: true,
72        }
73    }
74
75    pub fn module_name(&self) -> &str {
76        &self.module_name
77    }
78
79    /// Whether to include serialization methods.
80    pub fn with_serialization(mut self, serialization: bool) -> Self {
81        self.serialization = serialization;
82        self
83    }
84
85    /// Whether to include specialized methods for specific encodings.
86    pub fn with_encodings<I>(mut self, encodings: I) -> Self
87    where
88        I: IntoIterator<Item = Encoding>,
89    {
90        self.encodings = encodings.into_iter().collect();
91        self
92    }
93
94    /// Container names provided by external modules.
95    pub fn with_external_definitions(mut self, external_definitions: ExternalDefinitions) -> Self {
96        self.external_definitions = external_definitions;
97        self
98    }
99
100    /// Comments attached to particular entity.
101    pub fn with_comments(mut self, mut comments: DocComments) -> Self {
102        // Make sure comments end with a (single) newline.
103        for comment in comments.values_mut() {
104            *comment = format!("{}\n", comment.trim());
105        }
106        self.comments = comments;
107        self
108    }
109
110    /// Custom code attached to particular entity.
111    pub fn with_custom_code(mut self, code: CustomCode) -> Self {
112        self.custom_code = code;
113        self
114    }
115
116    /// Generate C-style enums (without variant data) as the target language
117    /// native enum type in supported languages.
118    pub fn with_c_style_enums(mut self, c_style_enums: bool) -> Self {
119        self.c_style_enums = c_style_enums;
120        self
121    }
122
123    /// Generate a package manifest file for the target language.
124    pub fn with_package_manifest(mut self, package_manifest: bool) -> Self {
125        self.package_manifest = package_manifest;
126        self
127    }
128}
129
130impl Encoding {
131    pub fn name(self) -> &'static str {
132        match self {
133            Encoding::Bincode => "bincode",
134            Encoding::Bcs => "bcs",
135        }
136    }
137}