blob: c55fb076cee8aa5ef872d695389d773611183709 [file] [log] [blame]
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07001use protobuf::descriptor::FieldOptions;
2use protobuf::descriptor::FileOptions;
3use protobuf::descriptor::MessageOptions;
4use protobuf::rustproto;
5
6/// Specifies style of generated code.
7#[derive(Default, Debug, Clone)]
8pub struct Customize {
9 /// Make oneof enum public.
10 pub expose_oneof: Option<bool>,
11 /// When true all fields are public, and accessors are not generated
12 pub expose_fields: Option<bool>,
13 /// When false, `get_`, `set_`, `mut_` etc. accessors are not generated
14 pub generate_accessors: Option<bool>,
15 /// Use `bytes::Bytes` for `bytes` fields
16 pub carllerche_bytes_for_bytes: Option<bool>,
17 /// Use `bytes::Bytes` for `string` fields
18 pub carllerche_bytes_for_string: Option<bool>,
19 /// Implement serde_derive for messages
20 pub serde_derive: Option<bool>,
21 /// When `serde_derive` is set, serde annotations will be guarded with `#[cfg(cfg, ...)]`.
22 pub serde_derive_cfg: Option<String>,
23 /// Enable lite runtime
24 pub lite_runtime: Option<bool>,
25 /// Used internally to generate protos bundled in protobuf crate
26 /// like `descriptor.proto`
27 pub inside_protobuf: Option<bool>,
28
29 // When adding more options please keep in sync with `parse_from_parameter` below.
30 /// Make sure `Customize` is always used with `..Default::default()`
31 /// for future compatibility.
32 pub _future_options: (),
33}
34
35#[derive(Debug)]
36pub enum CustomizeParseParameterError {
37 EqNotFound,
38 CannotParseBool,
39 UnknownOptionName(String),
40}
41
42pub type CustomizeParseParameterResult<T> = Result<T, CustomizeParseParameterError>;
43
44impl Customize {
45 /// Update fields of self with fields defined in other customize
46 pub fn update_with(&mut self, that: &Customize) {
47 if let Some(v) = that.expose_oneof {
48 self.expose_oneof = Some(v);
49 }
50 if let Some(v) = that.expose_fields {
51 self.expose_fields = Some(v);
52 }
53 if let Some(v) = that.generate_accessors {
54 self.generate_accessors = Some(v);
55 }
56 if let Some(v) = that.carllerche_bytes_for_bytes {
57 self.carllerche_bytes_for_bytes = Some(v);
58 }
59 if let Some(v) = that.carllerche_bytes_for_string {
60 self.carllerche_bytes_for_string = Some(v);
61 }
62 if let Some(v) = that.serde_derive {
63 self.serde_derive = Some(v);
64 }
65 if let Some(ref v) = that.serde_derive_cfg {
66 self.serde_derive_cfg = Some(v.clone());
67 }
68 if let Some(v) = that.lite_runtime {
69 self.lite_runtime = Some(v);
70 }
71 if let Some(v) = that.inside_protobuf {
72 self.inside_protobuf = Some(v);
73 }
74 }
75
76 /// Update unset fields of self with fields from other customize
77 pub fn set_defaults_from(&mut self, other: &Customize) {
78 let mut tmp = other.clone();
79 tmp.update_with(self);
80 *self = tmp;
81 }
82
83 /// Parse customize options from a string passed via protoc flag.
84 pub fn parse_from_parameter(parameter: &str) -> CustomizeParseParameterResult<Customize> {
85 fn parse_bool(v: &str) -> CustomizeParseParameterResult<bool> {
86 v.parse()
87 .map_err(|_| CustomizeParseParameterError::CannotParseBool)
88 }
89
90 let mut r = Customize::default();
91 for nv in parameter.split_whitespace() {
92 let eq = match nv.find('=') {
93 Some(eq) => eq,
94 None => return Err(CustomizeParseParameterError::EqNotFound),
95 };
96
97 let n = &nv[..eq];
98 let v = &nv[eq + 1..];
99
100 if n == "expose_oneof" {
101 r.expose_oneof = Some(parse_bool(v)?);
102 } else if n == "expose_fields" {
103 r.expose_fields = Some(parse_bool(v)?);
104 } else if n == "generate_accessors" {
105 r.generate_accessors = Some(parse_bool(v)?);
106 } else if n == "carllerche_bytes_for_bytes" {
107 r.carllerche_bytes_for_bytes = Some(parse_bool(v)?);
108 } else if n == "carllerche_bytes_for_string" {
109 r.carllerche_bytes_for_string = Some(parse_bool(v)?);
110 } else if n == "serde_derive" {
111 r.serde_derive = Some(parse_bool(v)?);
112 } else if n == "serde_derive_cfg" {
113 r.serde_derive_cfg = Some(v.to_owned());
114 } else if n == "lite_runtime" {
115 r.lite_runtime = Some(parse_bool(v)?);
116 } else if n == "inside_protobuf" {
117 r.inside_protobuf = Some(parse_bool(v)?);
118 } else {
119 return Err(CustomizeParseParameterError::UnknownOptionName(
120 n.to_owned(),
121 ));
122 }
123 }
124 Ok(r)
125 }
126}
127
128pub fn customize_from_rustproto_for_message(source: &MessageOptions) -> Customize {
129 let expose_oneof = rustproto::exts::expose_oneof.get(source);
130 let expose_fields = rustproto::exts::expose_fields.get(source);
131 let generate_accessors = rustproto::exts::generate_accessors.get(source);
132 let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes.get(source);
133 let carllerche_bytes_for_string = rustproto::exts::carllerche_bytes_for_string.get(source);
134 let serde_derive = rustproto::exts::serde_derive.get(source);
135 let serde_derive_cfg = rustproto::exts::serde_derive_cfg.get(source);
136 let lite_runtime = None;
137 let inside_protobuf = None;
138 Customize {
139 expose_oneof,
140 expose_fields,
141 generate_accessors,
142 carllerche_bytes_for_bytes,
143 carllerche_bytes_for_string,
144 serde_derive,
145 serde_derive_cfg,
146 lite_runtime,
147 inside_protobuf,
148 _future_options: (),
149 }
150}
151
152pub fn customize_from_rustproto_for_field(source: &FieldOptions) -> Customize {
153 let expose_oneof = None;
154 let expose_fields = rustproto::exts::expose_fields_field.get(source);
155 let generate_accessors = rustproto::exts::generate_accessors_field.get(source);
156 let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes_field.get(source);
157 let carllerche_bytes_for_string =
158 rustproto::exts::carllerche_bytes_for_string_field.get(source);
159 let serde_derive = None;
160 let serde_derive_cfg = None;
161 let lite_runtime = None;
162 let inside_protobuf = None;
163 Customize {
164 expose_oneof,
165 expose_fields,
166 generate_accessors,
167 carllerche_bytes_for_bytes,
168 carllerche_bytes_for_string,
169 serde_derive,
170 serde_derive_cfg,
171 lite_runtime,
172 inside_protobuf,
173 _future_options: (),
174 }
175}
176
177pub fn customize_from_rustproto_for_file(source: &FileOptions) -> Customize {
178 let expose_oneof = rustproto::exts::expose_oneof_all.get(source);
179 let expose_fields = rustproto::exts::expose_fields_all.get(source);
180 let generate_accessors = rustproto::exts::generate_accessors_all.get(source);
181 let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes_all.get(source);
182 let carllerche_bytes_for_string = rustproto::exts::carllerche_bytes_for_string_all.get(source);
183 let serde_derive = rustproto::exts::serde_derive_all.get(source);
184 let serde_derive_cfg = rustproto::exts::serde_derive_cfg_all.get(source);
185 let lite_runtime = rustproto::exts::lite_runtime_all.get(source);
186 let inside_protobuf = None;
187 Customize {
188 expose_oneof,
189 expose_fields,
190 generate_accessors,
191 carllerche_bytes_for_bytes,
192 carllerche_bytes_for_string,
193 serde_derive,
194 serde_derive_cfg,
195 lite_runtime,
196 inside_protobuf,
197 _future_options: (),
198 }
199}