protobuf_codegen/customize/
mod.rs1pub(crate) mod ctx;
2pub(crate) mod rustproto_proto;
3
4use std::fmt;
5use std::ops::Deref;
6use std::rc::Rc;
7
8use protobuf::reflect::EnumDescriptor;
9use protobuf::reflect::FieldDescriptor;
10use protobuf::reflect::FileDescriptor;
11use protobuf::reflect::MessageDescriptor;
12use protobuf::reflect::OneofDescriptor;
13
14pub trait CustomizeCallback: 'static {
16 fn file(&self, file: &FileDescriptor) -> Customize {
17 let _ = file;
18 Customize::default()
19 }
20
21 fn message(&self, message: &MessageDescriptor) -> Customize {
22 let _ = message;
23 Customize::default()
24 }
25
26 fn field(&self, field: &FieldDescriptor) -> Customize {
27 let _ = field;
28 Customize::default()
29 }
30
31 fn special_field(&self, message: &MessageDescriptor, field: &str) -> Customize {
32 let _ = (message, field);
33 Customize::default()
34 }
35
36 fn enumeration(&self, enum_type: &EnumDescriptor) -> Customize {
37 let _ = enum_type;
38 Customize::default()
39 }
40
41 fn oneof(&self, oneof: &OneofDescriptor) -> Customize {
42 let _ = oneof;
43 Customize::default()
44 }
45}
46
47pub(crate) struct CustomizeCallbackDefault;
48impl CustomizeCallback for CustomizeCallbackDefault {}
49
50#[derive(Clone)]
51pub(crate) struct CustomizeCallbackHolder(pub(crate) Rc<dyn CustomizeCallback>);
52
53impl CustomizeCallbackHolder {
54 pub(crate) fn new(callback: impl CustomizeCallback) -> CustomizeCallbackHolder {
55 CustomizeCallbackHolder(Rc::new(callback))
56 }
57}
58
59impl Deref for CustomizeCallbackHolder {
60 type Target = dyn CustomizeCallback;
61
62 fn deref(&self) -> &Self::Target {
63 &*self.0
64 }
65}
66
67impl Default for CustomizeCallbackHolder {
68 fn default() -> Self {
69 CustomizeCallbackHolder(Rc::new(CustomizeCallbackDefault))
70 }
71}
72
73impl PartialEq for CustomizeCallbackHolder {
74 fn eq(&self, other: &Self) -> bool {
75 Rc::ptr_eq(&self.0, &other.0)
76 }
77}
78
79impl fmt::Debug for CustomizeCallbackHolder {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 f.debug_struct("CustomizeCallbackWrapper")
82 .finish_non_exhaustive()
83 }
84}
85
86#[derive(Default, Debug, Clone, PartialEq)]
90pub struct Customize {
91 pub(crate) before: Option<String>,
93 pub(crate) generate_accessors: Option<bool>,
95 pub(crate) generate_getter: Option<bool>,
97 pub(crate) tokio_bytes: Option<bool>,
99 pub(crate) tokio_bytes_for_string: Option<bool>,
101 pub(crate) oneofs_non_exhaustive: Option<bool>,
103 pub(crate) lite_runtime: Option<bool>,
105 pub(crate) gen_mod_rs: Option<bool>,
111 pub(crate) inside_protobuf: Option<bool>,
114 pub(crate) btreemap: Option<bool>,
116}
117
118#[derive(Debug, thiserror::Error)]
119pub(crate) enum CustomizeParseParameterError {
120 #[error("Cannot parse bool option value: {:?}", .0)]
121 CannotParseBool(String),
122 #[error("Unknown option name: {:?}", .0)]
123 UnknownOptionName(String),
124}
125
126impl Customize {
127 pub fn before(mut self, before: &str) -> Self {
131 self.before = Some(before.to_owned());
132 self
133 }
134
135 pub fn generate_accessors(mut self, generate_accessors: bool) -> Self {
136 self.generate_accessors = Some(generate_accessors);
137 self
138 }
139
140 pub fn generate_getter(mut self, generate_getter: bool) -> Self {
141 self.generate_getter = Some(generate_getter);
142 self
143 }
144
145 pub fn tokio_bytes(mut self, tokio_bytes: bool) -> Self {
146 self.tokio_bytes = Some(tokio_bytes);
147 self
148 }
149
150 pub fn tokio_bytes_for_string(mut self, tokio_bytes_for_string: bool) -> Self {
151 self.tokio_bytes_for_string = Some(tokio_bytes_for_string);
152 self
153 }
154
155 pub fn oneofs_non_exhaustive(mut self, non_exhaustive: bool) -> Self {
156 self.oneofs_non_exhaustive = Some(non_exhaustive);
157 self
158 }
159
160 pub fn lite_runtime(mut self, lite_runtime: bool) -> Self {
166 self.lite_runtime = Some(lite_runtime);
167 self
168 }
169
170 pub fn gen_mod_rs(mut self, gen_mod_rs: bool) -> Self {
173 self.gen_mod_rs = Some(gen_mod_rs);
174 self
175 }
176
177 pub fn inside_protobuf(mut self, inside_protobuf: bool) -> Self {
179 self.inside_protobuf = Some(inside_protobuf);
180 self
181 }
182
183 pub fn btreemaps(self, use_btreemaps: bool) -> Self {
185 Self {
186 btreemap: Some(use_btreemaps),
187 ..self
188 }
189 }
190
191 pub fn update_with(&mut self, that: &Customize) {
193 if let Some(v) = &that.before {
194 self.before = Some(v.clone());
195 }
196 if let Some(v) = that.generate_accessors {
197 self.generate_accessors = Some(v);
198 }
199 if let Some(v) = that.generate_getter {
200 self.generate_getter = Some(v);
201 }
202 if let Some(v) = that.tokio_bytes {
203 self.tokio_bytes = Some(v);
204 }
205 if let Some(v) = that.tokio_bytes_for_string {
206 self.tokio_bytes_for_string = Some(v);
207 }
208 if let Some(v) = that.lite_runtime {
209 self.lite_runtime = Some(v);
210 }
211 if let Some(v) = that.gen_mod_rs {
212 self.gen_mod_rs = Some(v);
213 }
214 if let Some(v) = that.inside_protobuf {
215 self.inside_protobuf = Some(v);
216 }
217 if let Some(v) = that.btreemap {
218 self.btreemap = Some(v);
219 }
220 }
221
222 pub fn set_defaults_from(&mut self, other: &Customize) {
224 let mut tmp = other.clone();
225 tmp.update_with(self);
226 *self = tmp;
227 }
228
229 pub fn parse_from_parameter(parameter: &str) -> anyhow::Result<Customize> {
231 fn parse_bool(v: &str) -> anyhow::Result<bool> {
232 v.parse()
233 .map_err(|_| CustomizeParseParameterError::CannotParseBool(v.to_owned()).into())
234 }
235
236 let mut r = Customize::default();
237 for nv in parameter.split_whitespace() {
238 let (n, v) = match nv.find('=') {
239 Some(eq) => {
240 let n = &nv[..eq];
241 let v = &nv[eq + 1..];
242 (n, v)
243 }
244 None => (nv, "true"),
245 };
246
247 if n == "generate_accessors" {
248 r.generate_accessors = Some(parse_bool(v)?);
249 } else if n == "generate_getter" {
250 r.generate_getter = Some(parse_bool(v)?);
251 } else if n == "tokio_bytes" {
252 r.tokio_bytes = Some(parse_bool(v)?);
253 } else if n == "tokio_bytes_for_string" {
254 r.tokio_bytes_for_string = Some(parse_bool(v)?);
255 } else if n == "lite_runtime" {
256 r.lite_runtime = Some(parse_bool(v)?);
257 } else if n == "gen_mod_rs" {
258 r.gen_mod_rs = Some(parse_bool(v)?);
259 } else if n == "btreemap" {
260 r.btreemap = Some(parse_bool(v)?);
261 } else if n == "inside_protobuf" {
262 r.inside_protobuf = Some(parse_bool(v)?);
263 } else if n == "lite" {
264 r.lite_runtime = Some(parse_bool(v)?);
267 } else {
268 return Err(CustomizeParseParameterError::UnknownOptionName(n.to_owned()).into());
269 }
270 }
271 Ok(r)
272 }
273}