1pub mod errors;
2mod keywords;
3mod parser;
4mod scc;
5pub mod types;
6
7use errors::{Error, Result};
8use std::path::{Path, PathBuf};
9use types::Config;
10
11#[derive(Debug, Default)]
50pub struct ConfigBuilder {
51 in_files: Vec<PathBuf>,
52 out_file: Option<PathBuf>,
53 include_paths: Vec<PathBuf>,
54 single_module: bool,
55 no_output: bool,
56 error_cycle: bool,
57 headers: bool,
58 dont_use_cow: bool,
59 custom_struct_derive: Vec<String>,
60 custom_repr: Option<String>,
61 owned: bool,
62 nostd: bool,
63 hashbrown: bool,
64 gen_info: bool,
65 add_deprecated_fields: bool,
66 generate_getters: bool,
67}
68
69impl ConfigBuilder {
70 pub fn new<P: AsRef<Path>>(
71 in_files: &[P],
72 output: Option<&P>,
73 output_dir: Option<&P>,
74 include_paths: &[P],
75 ) -> Result<ConfigBuilder> {
76 let in_files = in_files
77 .iter()
78 .map(|f| f.as_ref().into())
79 .collect::<Vec<PathBuf>>();
80 let output = output.map(|f| f.as_ref().into());
81 let output_dir: Option<PathBuf> = output_dir.map(|f| f.as_ref().into());
82 let mut include_paths = include_paths
83 .iter()
84 .map(|f| f.as_ref().into())
85 .collect::<Vec<PathBuf>>();
86
87 if in_files.is_empty() {
88 return Err(Error::NoProto);
89 }
90
91 for f in &in_files {
92 if !f.exists() {
93 return Err(Error::InputFile(format!("{}", f.display())));
94 }
95 }
96
97 let out_file = match (output, output_dir) {
98 (Some(_), None) if in_files.len() > 1 => {
99 return Err(Error::OutputMultipleInputs);
100 }
101 (Some(output), None) => Some(output),
102 (None, Some(output_dir)) => {
103 if !output_dir.is_dir() {
104 return Err(Error::OutputDirectory(format!("{}", output_dir.display())));
105 }
106 Some(output_dir)
107 }
108 (Some(_), Some(_)) => {
109 return Err(Error::OutputAndOutputDir);
110 }
111 (None, None) => None,
112 };
113
114 let default = PathBuf::from(".");
115 if include_paths.is_empty() || !include_paths.contains(&default) {
116 include_paths.push(default);
117 }
118
119 Ok(ConfigBuilder {
120 in_files,
121 out_file,
122 include_paths,
123 headers: true,
124 ..Default::default()
125 })
126 }
127
128 pub fn single_module(
130 mut self,
131 val: bool,
132 ) -> Self {
133 self.single_module = val;
134 self
135 }
136
137 pub fn no_output(
140 mut self,
141 val: bool,
142 ) -> Self {
143 self.no_output = val;
144 self
145 }
146
147 pub fn error_cycle(
149 mut self,
150 val: bool,
151 ) -> Self {
152 self.error_cycle = val;
153 self
154 }
155
156 pub fn headers(
158 mut self,
159 val: bool,
160 ) -> Self {
161 self.headers = val;
162 self
163 }
164
165 pub fn custom_struct_derive(
167 mut self,
168 val: Vec<String>,
169 ) -> Self {
170 self.custom_struct_derive = val;
171 self
172 }
173
174 pub fn custom_repr(
176 mut self,
177 val: Option<String>,
178 ) -> Self {
179 self.custom_repr = val;
180 self
181 }
182
183 pub fn dont_use_cow(
185 mut self,
186 val: bool,
187 ) -> Self {
188 self.dont_use_cow = val;
189 self
190 }
191
192 pub fn owned(
194 mut self,
195 val: bool,
196 ) -> Self {
197 self.owned = val;
198 self
199 }
200
201 pub fn nostd(
203 mut self,
204 val: bool,
205 ) -> Self {
206 self.nostd = val;
207 self
208 }
209
210 pub fn hashbrown(
214 mut self,
215 val: bool,
216 ) -> Self {
217 self.hashbrown = val;
218 self
219 }
220
221 pub fn gen_info(
223 mut self,
224 val: bool,
225 ) -> Self {
226 self.gen_info = val;
227 self
228 }
229
230 pub fn add_deprecated_fields(
232 mut self,
233 val: bool,
234 ) -> Self {
235 self.add_deprecated_fields = val;
236 self
237 }
238
239 pub fn generate_getters(
241 mut self,
242 val: bool,
243 ) -> Self {
244 self.generate_getters = val;
245 self
246 }
247
248 pub fn build(self) -> Vec<Config> {
250 self.in_files
251 .iter()
252 .map(|in_file| {
253 let mut out_file = in_file.with_extension("rs");
254
255 if let Some(ref ofile) = self.out_file {
256 if ofile.is_dir() {
257 out_file = ofile.join(out_file.file_name().unwrap());
258 } else {
259 out_file = ofile.into();
260 }
261 }
262
263 Config {
264 in_file: in_file.to_owned(),
265 out_file,
266 import_search_path: self.include_paths.clone(),
267 single_module: self.single_module,
268 no_output: self.no_output,
269 error_cycle: self.error_cycle,
270 headers: self.headers,
271 dont_use_cow: self.dont_use_cow, custom_struct_derive: self.custom_struct_derive.clone(),
273 custom_repr: self.custom_repr.clone(),
274 custom_rpc_generator: Box::new(|_, _| Ok(())),
275 custom_includes: Vec::new(),
276 owned: self.owned,
277 nostd: self.nostd,
278 hashbrown: self.hashbrown,
279 gen_info: self.gen_info,
280 add_deprecated_fields: self.add_deprecated_fields,
281 generate_getters: self.generate_getters,
282 }
283 })
284 .collect()
285 }
286}