blob: 855b78545a8c1bafc198230e02f90a2a9a392282 [file] [log] [blame]
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07001// TODO: used by grpc-rust, should move it into separate crate.
2#![doc(hidden)]
3
Haibo Huangba676d32020-08-12 13:52:13 -07004use inside::protobuf_crate_path;
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07005use std::io::Write;
Haibo Huangba676d32020-08-12 13:52:13 -07006use Customize;
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07007
8/// Field visibility.
9pub enum Visibility {
10 Public,
11 Default,
12}
13
14pub struct CodeWriter<'a> {
15 writer: &'a mut (dyn Write + 'a),
16 indent: String,
17}
18
19impl<'a> CodeWriter<'a> {
20 pub fn new(writer: &'a mut dyn Write) -> CodeWriter<'a> {
21 CodeWriter {
22 writer: writer,
23 indent: "".to_string(),
24 }
25 }
26
27 pub fn write_line<S: AsRef<str>>(&mut self, line: S) {
28 (if line.as_ref().is_empty() {
29 self.writer.write_all("\n".as_bytes())
30 } else {
31 let s: String = [self.indent.as_ref(), line.as_ref(), "\n"].concat();
32 self.writer.write_all(s.as_bytes())
33 })
34 .unwrap();
35 }
36
37 pub fn write_generated(&mut self) {
38 self.write_line("// This file is generated. Do not edit");
39 self.write_generated_common();
40 }
41
42 pub fn write_generated_by(&mut self, pkg: &str, version: &str) {
43 self.write_line(format!(
44 "// This file is generated by {pkg} {version}. Do not edit",
45 pkg = pkg,
46 version = version
47 ));
48 self.write_generated_common();
49 }
50
51 fn write_generated_common(&mut self) {
52 // https://secure.phabricator.com/T784
53 self.write_line("// @generated");
54
55 self.write_line("");
56 self.comment("https://github.com/rust-lang/rust-clippy/issues/702");
57 self.write_line("#![allow(unknown_lints)]");
58 self.write_line("#![allow(clippy::all)]");
59 self.write_line("");
Haibo Huang72fec012020-07-10 20:24:04 -070060 self.write_line("#![allow(unused_attributes)]");
Ivan Lozanob32d5e82020-08-26 15:19:37 -040061 // ANDROID CHANGE: comment out rustfmt::skip to fix compilation error.
62 //self.write_line("#![rustfmt::skip]");
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070063 self.write_line("");
64 self.write_line("#![allow(box_pointers)]");
65 self.write_line("#![allow(dead_code)]");
66 self.write_line("#![allow(missing_docs)]");
67 self.write_line("#![allow(non_camel_case_types)]");
68 self.write_line("#![allow(non_snake_case)]");
69 self.write_line("#![allow(non_upper_case_globals)]");
70 self.write_line("#![allow(trivial_casts)]");
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -070071 self.write_line("#![allow(unused_imports)]");
72 self.write_line("#![allow(unused_results)]");
73 }
74
75 pub fn todo(&mut self, message: &str) {
76 self.write_line(format!("panic!(\"TODO: {}\");", message));
77 }
78
79 pub fn unimplemented(&mut self) {
80 self.write_line(format!("unimplemented!();"));
81 }
82
83 pub fn indented<F>(&mut self, cb: F)
84 where
85 F: Fn(&mut CodeWriter),
86 {
87 cb(&mut CodeWriter {
88 writer: self.writer,
89 indent: format!("{} ", self.indent),
90 });
91 }
92
93 #[allow(dead_code)]
94 pub fn commented<F>(&mut self, cb: F)
95 where
96 F: Fn(&mut CodeWriter),
97 {
98 cb(&mut CodeWriter {
99 writer: self.writer,
100 indent: format!("// {}", self.indent),
101 });
102 }
103
104 pub fn pub_const(&mut self, name: &str, field_type: &str, init: &str) {
105 self.write_line(&format!("pub const {}: {} = {};", name, field_type, init));
106 }
107
Haibo Huangba676d32020-08-12 13:52:13 -0700108 pub fn lazy_static(&mut self, name: &str, ty: &str, customize: &Customize) {
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700109 self.write_line(&format!(
Haibo Huang72fec012020-07-10 20:24:04 -0700110 "static {}: {}::rt::LazyV2<{}> = {}::rt::LazyV2::INIT;",
Haibo Huangba676d32020-08-12 13:52:13 -0700111 name,
112 protobuf_crate_path(customize),
113 ty,
114 protobuf_crate_path(customize),
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700115 ));
116 }
117
Haibo Huangba676d32020-08-12 13:52:13 -0700118 pub fn lazy_static_decl_get<F>(&mut self, name: &str, ty: &str, customize: &Customize, init: F)
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700119 where
120 F: Fn(&mut CodeWriter),
121 {
Haibo Huangba676d32020-08-12 13:52:13 -0700122 self.lazy_static(name, ty, customize);
Haibo Huang72fec012020-07-10 20:24:04 -0700123 self.write_line(&format!("{}.get(|| {{", name));
124 self.indented(|w| init(w));
125 self.write_line(&format!("}})"));
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700126 }
127
Haibo Huangba676d32020-08-12 13:52:13 -0700128 pub fn lazy_static_decl_get_simple(
129 &mut self,
130 name: &str,
131 ty: &str,
132 init: &str,
133 customize: &Customize,
134 ) {
135 self.lazy_static(name, ty, customize);
Haibo Huang72fec012020-07-10 20:24:04 -0700136 self.write_line(&format!("{}.get({})", name, init));
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -0700137 }
138
139 pub fn block<F>(&mut self, first_line: &str, last_line: &str, cb: F)
140 where
141 F: Fn(&mut CodeWriter),
142 {
143 self.write_line(first_line);
144 self.indented(cb);
145 self.write_line(last_line);
146 }
147
148 pub fn expr_block<F>(&mut self, prefix: &str, cb: F)
149 where
150 F: Fn(&mut CodeWriter),
151 {
152 self.block(&format!("{} {{", prefix), "}", cb);
153 }
154
155 pub fn stmt_block<S: AsRef<str>, F>(&mut self, prefix: S, cb: F)
156 where
157 F: Fn(&mut CodeWriter),
158 {
159 self.block(&format!("{} {{", prefix.as_ref()), "};", cb);
160 }
161
162 pub fn unsafe_expr<F>(&mut self, cb: F)
163 where
164 F: Fn(&mut CodeWriter),
165 {
166 self.expr_block("unsafe", cb);
167 }
168
169 pub fn impl_self_block<S: AsRef<str>, F>(&mut self, name: S, cb: F)
170 where
171 F: Fn(&mut CodeWriter),
172 {
173 self.expr_block(&format!("impl {}", name.as_ref()), cb);
174 }
175
176 pub fn impl_for_block<S1: AsRef<str>, S2: AsRef<str>, F>(&mut self, tr: S1, ty: S2, cb: F)
177 where
178 F: Fn(&mut CodeWriter),
179 {
180 self.impl_args_for_block(&[], tr.as_ref(), ty.as_ref(), cb);
181 }
182
183 pub fn impl_args_for_block<F>(&mut self, args: &[&str], tr: &str, ty: &str, cb: F)
184 where
185 F: Fn(&mut CodeWriter),
186 {
187 let args_str = if args.is_empty() {
188 "".to_owned()
189 } else {
190 format!("<{}>", args.join(", "))
191 };
192 self.expr_block(&format!("impl{} {} for {}", args_str, tr, ty), cb);
193 }
194
195 pub fn unsafe_impl(&mut self, what: &str, for_what: &str) {
196 self.write_line(&format!("unsafe impl {} for {} {{}}", what, for_what));
197 }
198
199 pub fn pub_struct<S: AsRef<str>, F>(&mut self, name: S, cb: F)
200 where
201 F: Fn(&mut CodeWriter),
202 {
203 self.expr_block(&format!("pub struct {}", name.as_ref()), cb);
204 }
205
206 pub fn def_struct<S: AsRef<str>, F>(&mut self, name: S, cb: F)
207 where
208 F: Fn(&mut CodeWriter),
209 {
210 self.expr_block(&format!("struct {}", name.as_ref()), cb);
211 }
212
213 pub fn pub_enum<F>(&mut self, name: &str, cb: F)
214 where
215 F: Fn(&mut CodeWriter),
216 {
217 self.expr_block(&format!("pub enum {}", name), cb);
218 }
219
220 pub fn pub_trait<F>(&mut self, name: &str, cb: F)
221 where
222 F: Fn(&mut CodeWriter),
223 {
224 self.expr_block(&format!("pub trait {}", name), cb);
225 }
226
227 pub fn pub_trait_extend<F>(&mut self, name: &str, extend: &str, cb: F)
228 where
229 F: Fn(&mut CodeWriter),
230 {
231 self.expr_block(&format!("pub trait {} : {}", name, extend), cb);
232 }
233
234 pub fn field_entry(&mut self, name: &str, value: &str) {
235 self.write_line(&format!("{}: {},", name, value));
236 }
237
238 pub fn field_decl(&mut self, name: &str, field_type: &str) {
239 self.write_line(&format!("{}: {},", name, field_type));
240 }
241
242 pub fn pub_field_decl(&mut self, name: &str, field_type: &str) {
243 self.write_line(&format!("pub {}: {},", name, field_type));
244 }
245
246 pub fn field_decl_vis(&mut self, vis: Visibility, name: &str, field_type: &str) {
247 match vis {
248 Visibility::Public => self.pub_field_decl(name, field_type),
249 Visibility::Default => self.field_decl(name, field_type),
250 }
251 }
252
253 pub fn derive(&mut self, derive: &[&str]) {
254 let v: Vec<String> = derive.iter().map(|&s| s.to_string()).collect();
255 self.write_line(&format!("#[derive({})]", v.join(",")));
256 }
257
258 pub fn allow(&mut self, what: &[&str]) {
259 let v: Vec<String> = what.iter().map(|&s| s.to_string()).collect();
260 self.write_line(&format!("#[allow({})]", v.join(",")));
261 }
262
263 pub fn comment(&mut self, comment: &str) {
264 if comment.is_empty() {
265 self.write_line("//");
266 } else {
267 self.write_line(&format!("// {}", comment));
268 }
269 }
270
271 pub fn fn_def(&mut self, sig: &str) {
272 self.write_line(&format!("fn {};", sig));
273 }
274
275 pub fn fn_block<F>(&mut self, public: bool, sig: &str, cb: F)
276 where
277 F: Fn(&mut CodeWriter),
278 {
279 if public {
280 self.expr_block(&format!("pub fn {}", sig), cb);
281 } else {
282 self.expr_block(&format!("fn {}", sig), cb);
283 }
284 }
285
286 pub fn pub_fn<F>(&mut self, sig: &str, cb: F)
287 where
288 F: Fn(&mut CodeWriter),
289 {
290 self.fn_block(true, sig, cb);
291 }
292
293 pub fn def_fn<F>(&mut self, sig: &str, cb: F)
294 where
295 F: Fn(&mut CodeWriter),
296 {
297 self.fn_block(false, sig, cb);
298 }
299
300 pub fn def_mod<F>(&mut self, name: &str, cb: F)
301 where
302 F: Fn(&mut CodeWriter),
303 {
304 self.expr_block(&format!("mod {}", name), cb)
305 }
306
307 pub fn pub_mod<F>(&mut self, name: &str, cb: F)
308 where
309 F: Fn(&mut CodeWriter),
310 {
311 self.expr_block(&format!("pub mod {}", name), cb)
312 }
313
314 pub fn while_block<S: AsRef<str>, F>(&mut self, cond: S, cb: F)
315 where
316 F: Fn(&mut CodeWriter),
317 {
318 self.expr_block(&format!("while {}", cond.as_ref()), cb);
319 }
320
321 // if ... { ... }
322 pub fn if_stmt<S: AsRef<str>, F>(&mut self, cond: S, cb: F)
323 where
324 F: Fn(&mut CodeWriter),
325 {
326 self.expr_block(&format!("if {}", cond.as_ref()), cb);
327 }
328
329 // if ... {} else { ... }
330 pub fn if_else_stmt<S: AsRef<str>, F>(&mut self, cond: S, cb: F)
331 where
332 F: Fn(&mut CodeWriter),
333 {
334 self.write_line(&format!("if {} {{", cond.as_ref()));
335 self.write_line("} else {");
336 self.indented(cb);
337 self.write_line("}");
338 }
339
340 // if let ... = ... { ... }
341 pub fn if_let_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
342 where
343 F: Fn(&mut CodeWriter),
344 {
345 self.if_stmt(&format!("let {} = {}", decl, expr), cb);
346 }
347
348 // if let ... = ... { } else { ... }
349 pub fn if_let_else_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
350 where
351 F: Fn(&mut CodeWriter),
352 {
353 self.if_else_stmt(&format!("let {} = {}", decl, expr), cb);
354 }
355
356 pub fn for_stmt<S1: AsRef<str>, S2: AsRef<str>, F>(&mut self, over: S1, varn: S2, cb: F)
357 where
358 F: Fn(&mut CodeWriter),
359 {
360 self.stmt_block(&format!("for {} in {}", varn.as_ref(), over.as_ref()), cb)
361 }
362
363 pub fn match_block<S: AsRef<str>, F>(&mut self, value: S, cb: F)
364 where
365 F: Fn(&mut CodeWriter),
366 {
367 self.stmt_block(&format!("match {}", value.as_ref()), cb);
368 }
369
370 pub fn match_expr<S: AsRef<str>, F>(&mut self, value: S, cb: F)
371 where
372 F: Fn(&mut CodeWriter),
373 {
374 self.expr_block(&format!("match {}", value.as_ref()), cb);
375 }
376
377 pub fn case_block<S: AsRef<str>, F>(&mut self, cond: S, cb: F)
378 where
379 F: Fn(&mut CodeWriter),
380 {
381 self.block(&format!("{} => {{", cond.as_ref()), "},", cb);
382 }
383
384 pub fn case_expr<S1: AsRef<str>, S2: AsRef<str>>(&mut self, cond: S1, body: S2) {
385 self.write_line(&format!("{} => {},", cond.as_ref(), body.as_ref()));
386 }
387}