1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
//! Interface for configuring and running the generator.
use crate::cpp_data::CppPath;
use crate::processor::ProcessingStep;
use ritual_common;
use ritual_common::cpp_build_config::{CppBuildConfig, CppBuildPaths};
use ritual_common::toml;
use std::path::PathBuf;
/// Information about an extra non-`cpp_to_rust`-based dependency.
#[derive(Default, Debug, Clone)]
pub struct CrateDependency {
name: String,
version: String,
local_path: Option<PathBuf>,
}
impl CrateDependency {
/// Name of the crate (as in `Cargo.toml`)
pub fn name(&self) -> &str {
&self.name
}
/// Version of the crate (as in `Cargo.toml`)
pub fn version(&self) -> &str {
&self.version
}
/// Local path to the dependency (if present).
pub fn local_path(&self) -> Option<&PathBuf> {
self.local_path.as_ref()
}
}
/// Information about the crate being generated.
/// Most of information in this object will be used in
/// the output `Cargo.toml`.
#[derive(Default, Debug, Clone)]
pub struct CrateProperties {
/// Name of the crate
name: String,
/// Version of the crate (must be in compliance with cargo requirements)
version: String,
/// Extra properties to be merged with auto generated content of `Cargo.toml`
custom_fields: toml::value::Table,
/// Extra dependencies for output `Cargo.toml`
dependencies: Vec<CrateDependency>,
/// Extra build dependencies for output `Cargo.toml`
build_dependencies: Vec<CrateDependency>,
/// Don't add default dependencies to `Cargo.toml`
remove_default_dependencies: bool,
/// Don't add default build dependencies to `Cargo.toml`
remove_default_build_dependencies: bool,
}
impl CrateProperties {
/// Creates a new object with `name` and `version`.
pub fn new<S1: Into<String>, S2: Into<String>>(name: S1, version: S2) -> CrateProperties {
CrateProperties {
name: name.into(),
version: version.into(),
custom_fields: Default::default(),
dependencies: Vec::new(),
build_dependencies: Vec::new(),
remove_default_dependencies: false,
remove_default_build_dependencies: false,
}
}
/// Adds an extra non-`cpp_to_rust`-based dependency with
/// `name`, `version` and optionally `local_path`.
pub fn add_dependency<S1: Into<String>, S2: Into<String>>(
&mut self,
name: S1,
version: S2,
local_path: Option<PathBuf>,
) {
self.dependencies.push(CrateDependency {
name: name.into(),
version: version.into(),
local_path,
});
}
/// Adds an extra build dependency with
/// `name`, `version` and optionally `local_path`.
pub fn add_build_dependency<S1: Into<String>, S2: Into<String>>(
&mut self,
name: S1,
version: S2,
local_path: Option<PathBuf>,
) {
self.build_dependencies.push(CrateDependency {
name: name.into(),
version: version.into(),
local_path,
});
}
/// Removes default dependencies from output `Cargo.toml`. Default
/// dependencies are `libc`, `cpp_utils` and crates added using
/// `Config::set_dependent_cpp_crates`.
pub fn remove_default_dependencies(&mut self) {
self.remove_default_dependencies = true;
}
/// Removes default build dependencies from output `Cargo.toml`. Default
/// build dependency is `cpp_to_rust_build_tools`.
pub fn remove_default_build_dependencies(&mut self) {
self.remove_default_build_dependencies = true;
}
/// Sets custom fields for output `Cargo.toml`. These fields will
/// be added to auto-generated fields (or replace them in case of a name conflict).
pub fn set_custom_fields(&mut self, value: toml::value::Table) {
self.custom_fields = value;
}
/// Name of the crate
pub fn name(&self) -> &String {
&self.name
}
/// Version of the crate
pub fn version(&self) -> &String {
&self.version
}
/// Extra non-`cpp_to_rust`-based dependencies of the crate
pub fn dependencies(&self) -> &Vec<CrateDependency> {
&self.dependencies
}
/// Extra build dependencies of the crate
pub fn build_dependencies(&self) -> &Vec<CrateDependency> {
&self.build_dependencies
}
/// Returns true if default dependencies were removed.
pub fn should_remove_default_dependencies(&self) -> bool {
self.remove_default_dependencies
}
/// Returns true if default build dependencies were removed.
pub fn should_remove_default_build_dependencies(&self) -> bool {
self.remove_default_build_dependencies
}
pub fn custom_fields(&self) -> &toml::value::Table {
&self.custom_fields
}
}
/// The starting point of `cpp_to_rust` API.
/// Create a `Config` object, set its properties,
/// add custom functions if necessary, and start
/// the processing with `Config::exec`.
#[derive(Debug)]
pub struct Config {
// see setters documentation for information about these properties
crate_properties: CrateProperties,
cpp_lib_version: Option<String>,
crate_template_path: Option<PathBuf>,
dependent_cpp_crates: Vec<String>,
include_directives: Vec<PathBuf>,
target_include_paths: Vec<PathBuf>,
cpp_build_config: CppBuildConfig,
cpp_build_paths: CppBuildPaths,
cpp_parser_arguments: Vec<String>,
cpp_parser_blocked_names: Vec<CppPath>,
custom_processing_steps: Vec<ProcessingStep>,
// TODO: revisit fields below when new rust name generator is done
cpp_filtered_namespaces: Vec<CppPath>,
movable_types: Vec<CppPath>,
}
impl Config {
/// Creates a `Config`.
/// `crate_properties` are used in Cargo.toml of the generated crate.
pub fn new(crate_properties: CrateProperties) -> Config {
Config {
crate_properties,
crate_template_path: Default::default(),
dependent_cpp_crates: Default::default(),
cpp_build_paths: Default::default(),
target_include_paths: Default::default(),
include_directives: Default::default(),
cpp_parser_arguments: Default::default(),
cpp_parser_blocked_names: Default::default(),
cpp_filtered_namespaces: Default::default(),
cpp_build_config: Default::default(),
movable_types: Default::default(),
custom_processing_steps: Default::default(),
cpp_lib_version: None,
}
}
/// Sets the directory containing additional files for the crate.
/// Any files and directories found in the crate template will be copied
/// to the generated crate's directory, although some of them (such as `Cargo.toml`)
/// may be overwritten with the generates files. It's common to put `tests` and
/// `examples` subdirectories in the crate template so that `cargo` recognizes them
/// automatically in the generated crate.
///
/// If you want to add some extra code
/// to the generated modules, put `src/module_name.rs` file in the crate template and
/// add `include_generated!();` line in the file. This line will be replaced with
/// the generated content. You can also add extra modules as separate files,
/// but you'll also need to create `src/lib.rs` in the crate template and
/// declare new module in it using `[pub] mod module_name;`. Use `include_generated!();`
/// in `src/lib.rs` to include declaration of automatically generated modules.
///
/// If the crate template contains `rustfmt.toml` file, it's used to format the generated
/// Rust code instead of the default `rustfmt.toml`.
///
/// Creating crate template is optional. The generator can make a crate without a template.
pub fn set_crate_template_path<P: Into<PathBuf>>(&mut self, path: P) {
self.crate_template_path = Some(path.into());
}
/// Sets list of names of crates created with `cpp_to_rust`.
/// The generator will integrate API of the current library with its
/// dependencies and re-use their types.
pub fn set_dependent_cpp_crates(&mut self, paths: Vec<String>) {
self.dependent_cpp_crates = paths;
}
/// Adds a C++ identifier that should be skipped
/// by the C++ parser. Identifier can contain namespaces
/// and nested classes, with `::` separator (like in
/// C++ identifiers). Identifier may refer to a method,
/// a class, a enum or a namespace. All entities inside blacklisted
/// entity (e.g. the methods of a blocked class or
/// the contents of a blocked namespace)
/// will also be skipped.
/// All class methods with names matching the blocked name
/// will be skipped, regardless of class name.
pub fn add_cpp_parser_blocked_name(&mut self, path: CppPath) {
self.cpp_parser_blocked_names.push(path);
}
/// Adds multiple blocked names. See `Config::add_cpp_parser_blocked_name`.
pub fn add_cpp_parser_blocked_names<Iter>(&mut self, items: Iter)
where
Iter: IntoIterator<Item = CppPath>,
{
for item in items {
self.cpp_parser_blocked_names.push(item);
}
}
/// Adds a command line argument for clang C++ parser.
///
/// Note that this value is not used when building the wrapper library.
/// Use `Config::cpp_build_config_mut` or a similar method to
/// configure building the wrapper library.
pub fn add_cpp_parser_argument<P: Into<String>>(&mut self, lib: P) {
self.cpp_parser_arguments.push(lib.into());
}
/// Adds multiple command line arguments for clang C++ parser.
/// See `Config::add_cpp_parser_argument`.
pub fn add_cpp_parser_arguments<Item, Iter>(&mut self, items: Iter)
where
Item: Into<String>,
Iter: IntoIterator<Item = Item>,
{
for item in items {
self.cpp_parser_arguments.push(item.into());
}
}
/// Sets `CppBuildPaths` value for this config. These paths
/// are used for testing C++ methods while processing the library,
/// but they are not used when building the generated crate.
pub fn set_cpp_build_paths(&mut self, paths: CppBuildPaths) {
self.cpp_build_paths = paths;
}
/// Adds path to an include directory or an include file
/// of the target library.
/// Any C++ types and methods will be parsed and used only
/// if they are declared within one of files or directories
/// added with this method.
///
/// If no target include paths are added, all types and methods
/// will be used. Most libraries include system headers and
/// other libraries' header files, so this mode is often unwanted.
pub fn add_target_include_path<P: Into<PathBuf>>(&mut self, path: P) {
self.target_include_paths.push(path.into());
}
/// Adds an include directive. Each directive will be added
/// as `#include <path>` to the input file for the C++ parser.
/// File name only paths or relative paths should be used in this method.
pub fn add_include_directive<P: Into<PathBuf>>(&mut self, path: P) {
self.include_directives.push(path.into());
}
/// Adds a namespace to filter out before rust code generation.
pub fn add_cpp_filtered_namespace(&mut self, namespace: CppPath) {
self.cpp_filtered_namespaces.push(namespace);
}
/// Adds multiple namespaces to filter out before rust code generation.
pub fn add_cpp_filtered_namespaces(&mut self, namespaces: impl IntoIterator<Item = CppPath>) {
for namespace in namespaces {
self.cpp_filtered_namespaces.push(namespace);
}
}
/// Overrides automatic selection of type allocation place for `type_name` and uses `place`
/// instead. See `CppTypeAllocationPlace` for more information.
pub fn set_movable_types(&mut self, names: Vec<CppPath>) {
self.movable_types = names;
}
/// Sets `CppBuildConfig` value that will be passed to the build script
/// of the generated crate.
pub fn set_cpp_build_config(&mut self, cpp_build_config: CppBuildConfig) {
self.cpp_build_config = cpp_build_config;
}
/// Allows to change `CppBuildConfig` value that will be passed to the build script
/// of the generated crate.
pub fn cpp_build_config_mut(&mut self) -> &mut CppBuildConfig {
&mut self.cpp_build_config
}
pub fn set_cpp_lib_version<S: Into<String>>(&mut self, version: S) {
self.cpp_lib_version = Some(version.into());
}
pub fn cpp_lib_version(&self) -> Option<&str> {
self.cpp_lib_version.as_ref().map(|x| x.as_str())
}
pub fn add_custom_processing_step(&mut self, step: ProcessingStep) {
self.custom_processing_steps.push(step);
}
/// Returns crate properties passed to `Config::new`.
pub fn crate_properties(&self) -> &CrateProperties {
&self.crate_properties
}
/// Returns value set by `Config::set_crate_template_path`.
pub fn crate_template_path(&self) -> Option<&PathBuf> {
self.crate_template_path.as_ref()
}
/// Returns value set by `Config::set_dependent_cpp_crates`.
pub fn dependent_cpp_crates(&self) -> &[String] {
&self.dependent_cpp_crates
}
/// Returns names added with `Config::add_cpp_parser_blocked_name`
/// and similar methods.
pub fn cpp_parser_blocked_names(&self) -> &[CppPath] {
&self.cpp_parser_blocked_names
}
/// Returns names added with `Config::add_cpp_parser_argument`
/// and similar methods.
pub fn cpp_parser_arguments(&self) -> &[String] {
&self.cpp_parser_arguments
}
/// Returns values added by `Config::set_cpp_build_paths`.
pub fn cpp_build_paths(&self) -> &CppBuildPaths {
&self.cpp_build_paths
}
/// Returns values added by `Config::add_target_include_path`.
pub fn target_include_paths(&self) -> &[PathBuf] {
&self.target_include_paths
}
/// Returns values added by `Config::add_include_directive`.
pub fn include_directives(&self) -> &[PathBuf] {
&self.include_directives
}
/// Returns values added by `Config::add_cpp_filtered_namespace`.
pub fn cpp_filtered_namespaces(&self) -> &[CppPath] {
&self.cpp_filtered_namespaces
}
/// Returns current `CppBuildConfig` value.
pub fn cpp_build_config(&self) -> &CppBuildConfig {
&self.cpp_build_config
}
/// Returns values added by `Config::set_movable_types`.
/// Keys of the hash map are names of C++ types.
pub fn movable_types(&self) -> &[CppPath] {
&self.movable_types
}
pub fn custom_processing_steps(&self) -> &[ProcessingStep] {
&self.custom_processing_steps
}
}