1use std::{
2 fmt::Display,
3 io::{Result, Write},
4 path::Path,
5};
6
7use general::{cfg_condition, version_condition};
8
9use crate::{
10 config::{gobjects::GObject, WorkMode},
11 env::Env,
12 file_saver::*,
13 library::Member,
14 version::Version,
15};
16
17mod alias;
18mod bound;
19mod child_properties;
20mod constants;
21mod doc;
22mod enums;
23mod flags;
24pub mod function;
25mod function_body_chunk;
26mod functions;
27mod general;
28mod object;
29mod objects;
30mod parameter;
31mod properties;
32mod property_body;
33mod record;
34mod records;
35mod ref_mode;
36mod return_value;
37mod signal;
38mod signal_body;
39mod special_functions;
40mod sys;
41mod trait_impls;
42mod trampoline;
43mod trampoline_from_glib;
44mod visibility;
45pub use visibility::Visibility;
46mod trampoline_to_glib;
47pub mod translate_from_glib;
48pub mod translate_to_glib;
49
50pub fn generate(env: &Env) {
51 match env.config.work_mode {
52 WorkMode::Normal => normal_generate(env),
53 WorkMode::Sys => sys::generate(env),
54 WorkMode::Doc => doc::generate(env),
55 WorkMode::DisplayNotBound => {}
56 }
57}
58
59fn normal_generate(env: &Env) {
60 let mut mod_rs: Vec<String> = Vec::new();
61 let mut traits: Vec<String> = Vec::new();
62 let mut builders: Vec<String> = Vec::new();
63 let root_path = env.config.auto_path.as_path();
64
65 generate_single_version_file(env);
66 objects::generate(env, root_path, &mut mod_rs, &mut traits, &mut builders);
67 records::generate(env, root_path, &mut mod_rs);
68 enums::generate(env, root_path, &mut mod_rs);
69 flags::generate(env, root_path, &mut mod_rs);
70 alias::generate(env, root_path, &mut mod_rs);
71 functions::generate(env, root_path, &mut mod_rs);
72 constants::generate(env, root_path, &mut mod_rs);
73
74 generate_mod_rs(env, root_path, &mod_rs, &traits, &builders);
75}
76
77pub fn generate_mod_rs(
78 env: &Env,
79 root_path: &Path,
80 mod_rs: &[String],
81 traits: &[String],
82 builders: &[String],
83) {
84 let path = root_path.join("mod.rs");
85 save_to_file(path, env.config.make_backup, |w| {
86 general::start_comments(w, &env.config)?;
87 general::write_vec(w, mod_rs)?;
88 writeln!(w)?;
89 if !traits.is_empty() {
90 writeln!(w, "pub(crate) mod traits {{")?;
91 general::write_vec(w, traits)?;
92 writeln!(w, "}}")?;
93 }
94
95 if !builders.is_empty() {
96 writeln!(w, "pub(crate) mod builders {{")?;
97 general::write_vec(w, builders)?;
98 writeln!(w, "}}")?;
99 }
100 Ok(())
101 });
102}
103
104pub fn generate_single_version_file(env: &Env) {
105 if let Some(ref path) = env.config.single_version_file {
106 save_to_file(path, env.config.make_backup, |w| {
107 general::single_version_file(w, &env.config, "")
108 });
109 }
110}
111
112pub fn generate_default_impl<
113 'a,
114 D: Display,
115 F: Fn(&'a Member) -> Option<(Option<Version>, Option<&'a String>, D)>,
116>(
117 w: &mut dyn Write,
118 env: &Env,
119 config: &GObject,
120 type_name: &str,
121 type_version: Option<Version>,
122 mut members: impl Iterator<Item = &'a Member>,
123 callback: F,
124) -> Result<()> {
125 if let Some(ref default_value) = config.default_value {
126 let member = match members.find(|m| m.name == *default_value) {
127 Some(m) => m,
128 None => {
129 log::error!(
130 "type `{}` doesn't have a member named `{}`. Not generating default impl.",
131 type_name,
132 default_value,
133 );
134 return Ok(());
135 }
136 };
137 let (version, cfg_cond, member_name) = match callback(member) {
138 Some(n) => n,
139 None => {
140 log::error!(
141 "member `{}` on type `{}` isn't generated so no default impl.",
142 default_value,
143 type_name,
144 );
145 return Ok(());
146 }
147 };
148
149 version_condition(w, env, None, type_version, false, 0)?;
151 cfg_condition(w, config.cfg_condition.as_ref(), false, 0)?;
152 version_condition(w, env, None, version, false, 0)?;
154 cfg_condition(w, cfg_cond, false, 0)?;
155 writeln!(
156 w,
157 "\n\
158 impl Default for {type_name} {{\n\
159 \tfn default() -> Self {{\n\
160 \t\tSelf::{member_name}\n\
161 \t}}\n\
162 }}\n",
163 )
164 } else {
165 Ok(())
166 }
167}