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}
67
68impl ConfigBuilder {
69 pub fn new<P: AsRef<Path>>(
70 in_files: &[P],
71 output: Option<&P>,
72 output_dir: Option<&P>,
73 include_paths: &[P],
74 ) -> Result<ConfigBuilder> {
75 let in_files = in_files
76 .iter()
77 .map(|f| f.as_ref().into())
78 .collect::<Vec<PathBuf>>();
79 let output = output.map(|f| f.as_ref().into());
80 let output_dir: Option<PathBuf> = output_dir.map(|f| f.as_ref().into());
81 let mut include_paths = include_paths
82 .iter()
83 .map(|f| f.as_ref().into())
84 .collect::<Vec<PathBuf>>();
85
86 if in_files.is_empty() {
87 return Err(Error::NoProto);
88 }
89
90 for f in &in_files {
91 if !f.exists() {
92 return Err(Error::InputFile(format!("{}", f.display())));
93 }
94 }
95
96 let out_file = match (output, output_dir) {
97 (Some(_), None) if in_files.len() > 1 => return Err(Error::OutputMultipleInputs),
98 (Some(output), None) => Some(output),
99 (None, Some(output_dir)) => {
100 if !output_dir.is_dir() {
101 return Err(Error::OutputDirectory(format!("{}", output_dir.display())));
102 }
103 Some(output_dir)
104 }
105 (Some(_), Some(_)) => return Err(Error::OutputAndOutputDir),
106 (None, None) => None,
107 };
108
109 let default = PathBuf::from(".");
110 if include_paths.is_empty() || !include_paths.contains(&default) {
111 include_paths.push(default);
112 }
113
114 Ok(ConfigBuilder {
115 in_files,
116 out_file,
117 include_paths,
118 headers: true,
119 ..Default::default()
120 })
121 }
122
123 pub fn single_module(mut self, val: bool) -> Self {
125 self.single_module = val;
126 self
127 }
128
129 pub fn no_output(mut self, val: bool) -> Self {
132 self.no_output = val;
133 self
134 }
135
136 pub fn error_cycle(mut self, val: bool) -> Self {
138 self.error_cycle = val;
139 self
140 }
141
142 pub fn headers(mut self, val: bool) -> Self {
144 self.headers = val;
145 self
146 }
147
148 pub fn custom_struct_derive(mut self, val: Vec<String>) -> Self {
150 self.custom_struct_derive = val;
151 self
152 }
153
154 pub fn custom_repr(mut self, val: Option<String>) -> Self {
156 self.custom_repr = val;
157 self
158 }
159
160 pub fn dont_use_cow(mut self, val: bool) -> Self {
162 self.dont_use_cow = val;
163 self
164 }
165
166 pub fn owned(mut self, val: bool) -> Self {
168 self.owned = val;
169 self
170 }
171
172 pub fn nostd(mut self, val: bool) -> Self {
174 self.nostd = val;
175 self
176 }
177
178 pub fn hashbrown(mut self, val: bool) -> Self {
182 self.hashbrown = val;
183 self
184 }
185
186 pub fn gen_info(mut self, val: bool) -> Self {
188 self.gen_info = val;
189 self
190 }
191
192 pub fn add_deprecated_fields(mut self, val: bool) -> Self {
194 self.add_deprecated_fields = val;
195 self
196 }
197
198 pub fn build(self) -> Vec<Config> {
200 self.in_files
201 .iter()
202 .map(|in_file| {
203 let mut out_file = in_file.with_extension("rs");
204
205 if let Some(ref ofile) = self.out_file {
206 if ofile.is_dir() {
207 out_file = ofile.join(out_file.file_name().unwrap());
208 } else {
209 out_file = ofile.into();
210 }
211 }
212
213 Config {
214 in_file: in_file.to_owned(),
215 out_file,
216 import_search_path: self.include_paths.clone(),
217 single_module: self.single_module,
218 no_output: self.no_output,
219 error_cycle: self.error_cycle,
220 headers: self.headers,
221 dont_use_cow: self.dont_use_cow, custom_struct_derive: self.custom_struct_derive.clone(),
223 custom_repr: self.custom_repr.clone(),
224 custom_rpc_generator: Box::new(|_, _| Ok(())),
225 custom_includes: Vec::new(),
226 owned: self.owned,
227 nostd: self.nostd,
228 hashbrown: self.hashbrown,
229 gen_info: self.gen_info,
230 add_deprecated_fields: self.add_deprecated_fields,
231 }
232 })
233 .collect()
234 }
235}