1#![deny(unsafe_code)]
13
14mod enums;
15mod grouper;
16mod metadata;
17mod rustifier;
18mod structs;
19
20use std::io::{self, Write};
21
22use grammers_tl_parser::tl::{Category, Definition, Type};
23
24pub struct Outputs<W: Write> {
26 pub common: W,
28 pub types: W,
30 pub functions: W,
32 pub enums: W,
34}
35
36impl<W: Write> Outputs<W> {
37 pub fn flush(&mut self) -> std::io::Result<()> {
39 self.common.flush()?;
40 self.types.flush()?;
41 self.functions.flush()?;
42 self.enums.flush()
43 }
44}
45
46pub struct Config {
48 pub gen_name_for_id: bool,
50 pub deserializable_functions: bool,
52 pub impl_debug: bool,
54 pub impl_from_type: bool,
56 pub impl_from_enum: bool,
58 pub impl_serde: bool,
60}
61
62impl Default for Config {
63 fn default() -> Self {
64 Self {
65 gen_name_for_id: false,
66 deserializable_functions: false,
67 impl_debug: true,
68 impl_from_type: true,
69 impl_from_enum: true,
70 impl_serde: false,
71 }
72 }
73}
74
75const SPECIAL_CASED_TYPES: [&str; 1] = ["Bool"];
78
79fn ignore_type(ty: &Type) -> bool {
80 SPECIAL_CASED_TYPES.iter().any(|&x| x == ty.name)
81}
82
83pub fn generate_rust_code<W: Write>(
85 outputs: &mut Outputs<W>,
86 definitions: &[Definition],
87 layer: i32,
88 config: &Config,
89) -> io::Result<()> {
90 writeln!(
91 &mut outputs.common,
92 r#"/// The schema layer from which the definitions were generated.
93pub const LAYER: i32 = {layer};
94"#
95 )?;
96
97 if config.gen_name_for_id {
98 writeln!(
99 outputs.common,
100 r#"
101/// Return the name from the `.tl` definition corresponding to the provided definition identifier.
102pub fn name_for_id(id: u32) -> &'static str {{
103 match id {{
104 0x1cb5c415 => "vector","#
105 )?;
106 for def in definitions {
107 writeln!(
108 &mut outputs.common,
109 r#" 0x{:x} => "{}","#,
110 def.id,
111 def.full_name()
112 )?;
113 }
114
115 writeln!(
116 outputs.common,
117 r#"
118 _ => "(unknown)",
119 }}
120}}
121 "#,
122 )?;
123 }
124
125 let metadata = metadata::Metadata::new(definitions);
126 structs::write_category_mod(
127 &mut outputs.types,
128 Category::Types,
129 definitions,
130 &metadata,
131 config,
132 )?;
133 structs::write_category_mod(
134 &mut outputs.functions,
135 Category::Functions,
136 definitions,
137 &metadata,
138 config,
139 )?;
140 enums::write_enums_mod(&mut outputs.enums, definitions, &metadata, config)?;
141
142 Ok(())
143}