1 use protobuf::descriptor::FieldOptions;
2 use protobuf::descriptor::FileOptions;
3 use protobuf::descriptor::MessageOptions;
4 use protobuf::rustproto;
5 
6 /// Specifies style of generated code.
7 #[derive(Default, Debug, Clone)]
8 pub 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     /// Generate `mod.rs` in the output directory.
26     ///
27     /// This option allows inclusion of generated files from cargo output directory.
28     ///
29     /// This option will likely be on by default in rust-protobuf version 3.
30     pub gen_mod_rs: Option<bool>,
31     /// Used internally to generate protos bundled in protobuf crate
32     /// like `descriptor.proto`
33     pub inside_protobuf: Option<bool>,
34 
35     // When adding more options please keep in sync with `parse_from_parameter` below.
36     /// Make sure `Customize` is always used with `..Default::default()`
37     /// for future compatibility.
38     pub _future_options: (),
39 }
40 
41 #[derive(Debug)]
42 pub enum CustomizeParseParameterError {
43     EqNotFound,
44     CannotParseBool,
45     UnknownOptionName(String),
46 }
47 
48 pub type CustomizeParseParameterResult<T> = Result<T, CustomizeParseParameterError>;
49 
50 impl Customize {
51     /// Update fields of self with fields defined in other customize
update_with(&mut self, that: &Customize)52     pub fn update_with(&mut self, that: &Customize) {
53         if let Some(v) = that.expose_oneof {
54             self.expose_oneof = Some(v);
55         }
56         if let Some(v) = that.expose_fields {
57             self.expose_fields = Some(v);
58         }
59         if let Some(v) = that.generate_accessors {
60             self.generate_accessors = Some(v);
61         }
62         if let Some(v) = that.carllerche_bytes_for_bytes {
63             self.carllerche_bytes_for_bytes = Some(v);
64         }
65         if let Some(v) = that.carllerche_bytes_for_string {
66             self.carllerche_bytes_for_string = Some(v);
67         }
68         if let Some(v) = that.serde_derive {
69             self.serde_derive = Some(v);
70         }
71         if let Some(ref v) = that.serde_derive_cfg {
72             self.serde_derive_cfg = Some(v.clone());
73         }
74         if let Some(v) = that.lite_runtime {
75             self.lite_runtime = Some(v);
76         }
77         if let Some(v) = that.gen_mod_rs {
78             self.gen_mod_rs = Some(v);
79         }
80         if let Some(v) = that.inside_protobuf {
81             self.inside_protobuf = Some(v);
82         }
83     }
84 
85     /// Update unset fields of self with fields from other customize
set_defaults_from(&mut self, other: &Customize)86     pub fn set_defaults_from(&mut self, other: &Customize) {
87         let mut tmp = other.clone();
88         tmp.update_with(self);
89         *self = tmp;
90     }
91 
92     /// Parse customize options from a string passed via protoc flag.
parse_from_parameter(parameter: &str) -> CustomizeParseParameterResult<Customize>93     pub fn parse_from_parameter(parameter: &str) -> CustomizeParseParameterResult<Customize> {
94         fn parse_bool(v: &str) -> CustomizeParseParameterResult<bool> {
95             v.parse()
96                 .map_err(|_| CustomizeParseParameterError::CannotParseBool)
97         }
98 
99         let mut r = Customize::default();
100         for nv in parameter.split_whitespace() {
101             let eq = match nv.find('=') {
102                 Some(eq) => eq,
103                 None => return Err(CustomizeParseParameterError::EqNotFound),
104             };
105 
106             let n = &nv[..eq];
107             let v = &nv[eq + 1..];
108 
109             if n == "expose_oneof" {
110                 r.expose_oneof = Some(parse_bool(v)?);
111             } else if n == "expose_fields" {
112                 r.expose_fields = Some(parse_bool(v)?);
113             } else if n == "generate_accessors" {
114                 r.generate_accessors = Some(parse_bool(v)?);
115             } else if n == "carllerche_bytes_for_bytes" {
116                 r.carllerche_bytes_for_bytes = Some(parse_bool(v)?);
117             } else if n == "carllerche_bytes_for_string" {
118                 r.carllerche_bytes_for_string = Some(parse_bool(v)?);
119             } else if n == "serde_derive" {
120                 r.serde_derive = Some(parse_bool(v)?);
121             } else if n == "serde_derive_cfg" {
122                 r.serde_derive_cfg = Some(v.to_owned());
123             } else if n == "lite_runtime" {
124                 r.lite_runtime = Some(parse_bool(v)?);
125             } else if n == "gen_mod_rs" {
126                 r.gen_mod_rs = Some(parse_bool(v)?);
127             } else if n == "inside_protobuf" {
128                 r.inside_protobuf = Some(parse_bool(v)?);
129             } else {
130                 return Err(CustomizeParseParameterError::UnknownOptionName(
131                     n.to_owned(),
132                 ));
133             }
134         }
135         Ok(r)
136     }
137 }
138 
customize_from_rustproto_for_message(source: &MessageOptions) -> Customize139 pub fn customize_from_rustproto_for_message(source: &MessageOptions) -> Customize {
140     let expose_oneof = rustproto::exts::expose_oneof.get(source);
141     let expose_fields = rustproto::exts::expose_fields.get(source);
142     let generate_accessors = rustproto::exts::generate_accessors.get(source);
143     let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes.get(source);
144     let carllerche_bytes_for_string = rustproto::exts::carllerche_bytes_for_string.get(source);
145     let serde_derive = rustproto::exts::serde_derive.get(source);
146     let serde_derive_cfg = rustproto::exts::serde_derive_cfg.get(source);
147     let lite_runtime = None;
148     let gen_mod_rs = None;
149     let inside_protobuf = None;
150     Customize {
151         expose_oneof,
152         expose_fields,
153         generate_accessors,
154         carllerche_bytes_for_bytes,
155         carllerche_bytes_for_string,
156         serde_derive,
157         serde_derive_cfg,
158         lite_runtime,
159         gen_mod_rs,
160         inside_protobuf,
161         _future_options: (),
162     }
163 }
164 
customize_from_rustproto_for_field(source: &FieldOptions) -> Customize165 pub fn customize_from_rustproto_for_field(source: &FieldOptions) -> Customize {
166     let expose_oneof = None;
167     let expose_fields = rustproto::exts::expose_fields_field.get(source);
168     let generate_accessors = rustproto::exts::generate_accessors_field.get(source);
169     let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes_field.get(source);
170     let carllerche_bytes_for_string =
171         rustproto::exts::carllerche_bytes_for_string_field.get(source);
172     let serde_derive = None;
173     let serde_derive_cfg = None;
174     let lite_runtime = None;
175     let gen_mod_rs = None;
176     let inside_protobuf = None;
177     Customize {
178         expose_oneof,
179         expose_fields,
180         generate_accessors,
181         carllerche_bytes_for_bytes,
182         carllerche_bytes_for_string,
183         serde_derive,
184         serde_derive_cfg,
185         lite_runtime,
186         gen_mod_rs,
187         inside_protobuf,
188         _future_options: (),
189     }
190 }
191 
customize_from_rustproto_for_file(source: &FileOptions) -> Customize192 pub fn customize_from_rustproto_for_file(source: &FileOptions) -> Customize {
193     let expose_oneof = rustproto::exts::expose_oneof_all.get(source);
194     let expose_fields = rustproto::exts::expose_fields_all.get(source);
195     let generate_accessors = rustproto::exts::generate_accessors_all.get(source);
196     let carllerche_bytes_for_bytes = rustproto::exts::carllerche_bytes_for_bytes_all.get(source);
197     let carllerche_bytes_for_string = rustproto::exts::carllerche_bytes_for_string_all.get(source);
198     let serde_derive = rustproto::exts::serde_derive_all.get(source);
199     let serde_derive_cfg = rustproto::exts::serde_derive_cfg_all.get(source);
200     let lite_runtime = rustproto::exts::lite_runtime_all.get(source);
201     let gen_mod_rs = None;
202     let inside_protobuf = None;
203     Customize {
204         expose_oneof,
205         expose_fields,
206         generate_accessors,
207         carllerche_bytes_for_bytes,
208         carllerche_bytes_for_string,
209         serde_derive,
210         serde_derive_cfg,
211         lite_runtime,
212         inside_protobuf,
213         gen_mod_rs,
214         _future_options: (),
215     }
216 }
217