1use std::collections::{BTreeMap, HashMap};
6use std::default::Default;
7use std::str::FromStr;
8use std::{fmt, fs, path::Path as StdPath, path::PathBuf as StdPathBuf};
9
10use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
11use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
12
13use crate::bindgen::ir::annotation::AnnotationSet;
14use crate::bindgen::ir::path::Path;
15use crate::bindgen::ir::repr::ReprAlign;
16pub use crate::bindgen::rename::RenameRule;
17
18pub const VERSION: &str = env!("CARGO_PKG_VERSION");
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq)]
22pub enum Language {
23 Cxx,
24 C,
25 Cython,
26}
27
28impl FromStr for Language {
29 type Err = String;
30
31 fn from_str(s: &str) -> Result<Language, Self::Err> {
32 match s {
33 "cxx" => Ok(Language::Cxx),
34 "Cxx" => Ok(Language::Cxx),
35 "CXX" => Ok(Language::Cxx),
36 "cpp" => Ok(Language::Cxx),
37 "Cpp" => Ok(Language::Cxx),
38 "CPP" => Ok(Language::Cxx),
39 "c++" => Ok(Language::Cxx),
40 "C++" => Ok(Language::Cxx),
41 "c" => Ok(Language::C),
42 "C" => Ok(Language::C),
43 "cython" => Ok(Language::Cython),
44 "Cython" => Ok(Language::Cython),
45 _ => Err(format!("Unrecognized Language: '{}'.", s)),
46 }
47 }
48}
49
50deserialize_enum_str!(Language);
51
52impl Language {
53 pub(crate) fn typedef(self) -> &'static str {
54 match self {
55 Language::Cxx | Language::C => "typedef",
56 Language::Cython => "ctypedef",
57 }
58 }
59}
60
61#[derive(Debug, Clone, Copy)]
63#[allow(clippy::upper_case_acronyms)]
64#[derive(Default)]
65pub enum LineEndingStyle {
66 #[default]
68 LF,
69 CR,
71 CRLF,
73 Native,
75}
76
77impl LineEndingStyle {
78 pub fn as_str(&self) -> &'static str {
79 match self {
80 Self::LF => "\n",
81 Self::CR => "\r",
82 Self::CRLF => "\r\n",
83 Self::Native => {
84 #[cfg(target_os = "windows")]
85 {
86 Self::CRLF.as_str()
87 }
88 #[cfg(not(target_os = "windows"))]
89 {
90 Self::LF.as_str()
91 }
92 }
93 }
94 }
95}
96
97impl FromStr for LineEndingStyle {
98 type Err = String;
99
100 fn from_str(s: &str) -> Result<Self, Self::Err> {
101 match s.to_lowercase().as_ref() {
102 "native" => Ok(Self::Native),
103 "lf" => Ok(Self::LF),
104 "crlf" => Ok(Self::CRLF),
105 "cr" => Ok(Self::CR),
106 _ => Err(format!("Unrecognized line ending style: '{}'.", s)),
107 }
108 }
109}
110
111deserialize_enum_str!(LineEndingStyle);
112
113#[derive(Debug, Clone, PartialEq, Eq)]
115pub enum Braces {
116 SameLine,
117 NextLine,
118}
119
120impl FromStr for Braces {
121 type Err = String;
122
123 fn from_str(s: &str) -> Result<Braces, Self::Err> {
124 match s {
125 "SameLine" => Ok(Braces::SameLine),
126 "same_line" => Ok(Braces::SameLine),
127 "NextLine" => Ok(Braces::NextLine),
128 "next_line" => Ok(Braces::NextLine),
129 _ => Err(format!("Unrecognized Braces: '{}'.", s)),
130 }
131 }
132}
133
134deserialize_enum_str!(Braces);
135
136#[derive(Debug, Copy, Clone, PartialEq, Eq)]
138pub enum Layout {
139 Horizontal,
140 Vertical,
141 Auto,
142}
143
144impl FromStr for Layout {
145 type Err = String;
146
147 fn from_str(s: &str) -> Result<Layout, Self::Err> {
148 match s {
149 "Horizontal" => Ok(Layout::Horizontal),
150 "horizontal" => Ok(Layout::Horizontal),
151 "Vertical" => Ok(Layout::Vertical),
152 "vertical" => Ok(Layout::Vertical),
153 "Auto" => Ok(Layout::Auto),
154 "auto" => Ok(Layout::Auto),
155 _ => Err(format!("Unrecognized Layout: '{}'.", s)),
156 }
157 }
158}
159
160deserialize_enum_str!(Layout);
161
162#[derive(Debug, Clone, PartialEq, Eq, Copy)]
164pub enum DocumentationStyle {
165 C,
166 C99,
167 Doxy,
168 Cxx,
169 Auto,
170}
171
172impl FromStr for DocumentationStyle {
173 type Err = String;
174
175 fn from_str(s: &str) -> Result<DocumentationStyle, Self::Err> {
176 match s.to_lowercase().as_ref() {
177 "c" => Ok(DocumentationStyle::C),
178 "c99" => Ok(DocumentationStyle::C99),
179 "cxx" => Ok(DocumentationStyle::Cxx),
180 "c++" => Ok(DocumentationStyle::Cxx),
181 "doxy" => Ok(DocumentationStyle::Doxy),
182 "auto" => Ok(DocumentationStyle::Auto),
183 _ => Err(format!("Unrecognized documentation style: '{}'.", s)),
184 }
185 }
186}
187
188deserialize_enum_str!(DocumentationStyle);
189
190#[derive(Debug, Clone, Copy)]
192pub enum DocumentationLength {
193 Short,
194 Full,
195}
196
197impl FromStr for DocumentationLength {
198 type Err = String;
199
200 fn from_str(s: &str) -> Result<DocumentationLength, Self::Err> {
201 match s.to_lowercase().as_ref() {
202 "short" => Ok(DocumentationLength::Short),
203 "full" => Ok(DocumentationLength::Full),
204 _ => Err(format!("Unrecognized documentation style: '{}'.", s)),
205 }
206 }
207}
208
209deserialize_enum_str!(DocumentationLength);
210
211#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
213pub enum Style {
214 #[default]
215 Both,
216 Tag,
217 Type,
218}
219
220impl Style {
221 pub fn generate_tag(self) -> bool {
222 match self {
223 Style::Both | Style::Tag => true,
224 Style::Type => false,
225 }
226 }
227
228 pub fn generate_typedef(self) -> bool {
229 match self {
230 Style::Both | Style::Type => true,
231 Style::Tag => false,
232 }
233 }
234
235 pub fn cython_def(self) -> &'static str {
237 if self.generate_tag() {
238 "cdef "
239 } else {
240 "ctypedef "
241 }
242 }
243}
244
245impl FromStr for Style {
246 type Err = String;
247
248 fn from_str(s: &str) -> Result<Style, Self::Err> {
249 match s {
250 "Both" => Ok(Style::Both),
251 "both" => Ok(Style::Both),
252 "Tag" => Ok(Style::Tag),
253 "tag" => Ok(Style::Tag),
254 "Type" => Ok(Style::Type),
255 "type" => Ok(Style::Type),
256 _ => Err(format!("Unrecognized Style: '{}'.", s)),
257 }
258 }
259}
260
261deserialize_enum_str!(Style);
262
263#[derive(Debug, Clone, PartialEq, Eq)]
265pub enum ItemType {
266 Constants,
267 Globals,
268 Enums,
269 Structs,
270 Unions,
271 Typedefs,
272 OpaqueItems,
273 Functions,
274}
275
276impl FromStr for ItemType {
277 type Err = String;
278
279 fn from_str(s: &str) -> Result<Self, Self::Err> {
280 use self::ItemType::*;
281 Ok(match &*s.to_lowercase() {
282 "constants" => Constants,
283 "globals" => Globals,
284 "enums" => Enums,
285 "structs" => Structs,
286 "unions" => Unions,
287 "typedefs" => Typedefs,
288 "opaque" => OpaqueItems,
289 "functions" => Functions,
290 _ => return Err(format!("Unrecognized Style: '{}'.", s)),
291 })
292 }
293}
294
295deserialize_enum_str!(ItemType);
296
297#[derive(Debug, Clone, Copy, PartialEq, Eq)]
299pub enum SortKey {
300 Name,
301 None,
302}
303
304impl FromStr for SortKey {
305 type Err = String;
306
307 fn from_str(s: &str) -> Result<Self, Self::Err> {
308 use self::SortKey::*;
309 Ok(match &*s.to_lowercase() {
310 "name" => Name,
311 "none" => None,
312 _ => return Err(format!("Unrecognized sort option: '{}'.", s)),
313 })
314 }
315}
316
317deserialize_enum_str!(SortKey);
318
319#[derive(Debug, Clone, Deserialize, Default)]
321#[serde(rename_all = "snake_case")]
322#[serde(deny_unknown_fields)]
323#[serde(default)]
324pub struct ExportConfig {
325 pub include: Vec<String>,
328 pub exclude: Vec<String>,
330 pub rename: HashMap<String, String>,
332 pub pre_body: HashMap<String, String>,
334 pub body: HashMap<String, String>,
336 pub prefix: Option<String>,
338 pub item_types: Vec<ItemType>,
340 pub renaming_overrides_prefixing: bool,
342 pub mangle: MangleConfig,
344}
345
346#[derive(Debug, Clone, Deserialize, Default)]
348#[serde(rename_all = "snake_case")]
349#[serde(deny_unknown_fields)]
350#[serde(default)]
351pub struct MangleConfig {
352 pub rename_types: RenameRule,
354 pub remove_underscores: bool,
356}
357
358impl ExportConfig {
359 pub(crate) fn should_generate(&self, item_type: ItemType) -> bool {
360 self.item_types.is_empty() || self.item_types.contains(&item_type)
361 }
362
363 pub(crate) fn pre_body(&self, path: &Path) -> Option<&str> {
364 self.pre_body.get(path.name()).map(|s| s.trim_matches('\n'))
365 }
366
367 pub(crate) fn post_body(&self, path: &Path) -> Option<&str> {
368 self.body.get(path.name()).map(|s| s.trim_matches('\n'))
369 }
370
371 pub(crate) fn rename(&self, item_name: &mut String) {
372 if let Some(name) = self.rename.get(item_name) {
373 item_name.clone_from(name);
374 if self.renaming_overrides_prefixing {
375 return;
376 }
377 }
378 if let Some(ref prefix) = self.prefix {
379 item_name.insert_str(0, prefix);
380 }
381 }
382}
383
384#[derive(Debug, Default, Clone, Deserialize)]
386#[serde(rename_all = "snake_case")]
387#[serde(deny_unknown_fields)]
388#[serde(default)]
389pub struct LayoutConfig {
390 pub packed: Option<String>,
392 pub aligned_n: Option<String>,
395}
396
397impl LayoutConfig {
398 pub(crate) fn ensure_safe_to_represent(&self, align: &ReprAlign) -> Result<(), String> {
399 match (align, &self.packed, &self.aligned_n) {
400 (ReprAlign::Packed, None, _) => Err("Cannot safely represent #[repr(packed)] type without configured 'packed' annotation.".to_string()),
401 (ReprAlign::Align(_), _, None) => Err("Cannot safely represent #[repr(aligned(...))] type without configured 'aligned_n' annotation.".to_string()),
402 _ => Ok(()),
403 }
404 }
405}
406
407#[derive(Debug, Clone, Deserialize)]
409#[serde(rename_all = "snake_case")]
410#[serde(deny_unknown_fields)]
411#[serde(default)]
412pub struct FunctionConfig {
413 pub prefix: Option<String>,
415 pub postfix: Option<String>,
417 pub must_use: Option<String>,
419 pub deprecated: Option<String>,
421 pub deprecated_with_note: Option<String>,
423 pub args: Layout,
425 pub rename_args: RenameRule,
427 pub swift_name_macro: Option<String>,
429 pub sort_by: Option<SortKey>,
431 pub no_return: Option<String>,
433}
434
435impl Default for FunctionConfig {
436 fn default() -> FunctionConfig {
437 FunctionConfig {
438 prefix: None,
439 postfix: None,
440 must_use: None,
441 deprecated: None,
442 deprecated_with_note: None,
443 args: Layout::Auto,
444 rename_args: RenameRule::None,
445 swift_name_macro: None,
446 sort_by: None,
447 no_return: None,
448 }
449 }
450}
451
452impl FunctionConfig {
453 pub(crate) fn prefix(&self, annotations: &AnnotationSet) -> Option<String> {
454 if let Some(x) = annotations.atom("prefix") {
455 return x;
456 }
457 self.prefix.clone()
458 }
459
460 pub(crate) fn postfix(&self, annotations: &AnnotationSet) -> Option<String> {
461 if let Some(x) = annotations.atom("postfix") {
462 return x;
463 }
464 self.postfix.clone()
465 }
466}
467
468#[derive(Debug, Default, Clone, Deserialize)]
470#[serde(rename_all = "snake_case")]
471#[serde(deny_unknown_fields)]
472#[serde(default)]
473pub struct StructConfig {
474 pub rename_fields: RenameRule,
476 pub derive_constructor: bool,
479 pub derive_eq: bool,
481 pub derive_neq: bool,
483 pub derive_lt: bool,
485 pub derive_lte: bool,
487 pub derive_gt: bool,
489 pub derive_gte: bool,
491 pub derive_ostream: bool,
493 pub associated_constants_in_body: bool,
496 pub rename_associated_constant: RenameRule,
499 pub must_use: Option<String>,
501 pub deprecated: Option<String>,
503 pub deprecated_with_note: Option<String>,
505}
506
507impl StructConfig {
508 pub(crate) fn derive_constructor(&self, annotations: &AnnotationSet) -> bool {
509 if let Some(x) = annotations.bool("derive-constructor") {
510 return x;
511 }
512 self.derive_constructor
513 }
514 pub(crate) fn derive_eq(&self, annotations: &AnnotationSet) -> bool {
515 if let Some(x) = annotations.bool("derive-eq") {
516 return x;
517 }
518 self.derive_eq
519 }
520 pub(crate) fn derive_neq(&self, annotations: &AnnotationSet) -> bool {
521 if let Some(x) = annotations.bool("derive-neq") {
522 return x;
523 }
524 self.derive_neq
525 }
526 pub(crate) fn derive_lt(&self, annotations: &AnnotationSet) -> bool {
527 if let Some(x) = annotations.bool("derive-lt") {
528 return x;
529 }
530 self.derive_lt
531 }
532 pub(crate) fn derive_lte(&self, annotations: &AnnotationSet) -> bool {
533 if let Some(x) = annotations.bool("derive-lte") {
534 return x;
535 }
536 self.derive_lte
537 }
538 pub(crate) fn derive_gt(&self, annotations: &AnnotationSet) -> bool {
539 if let Some(x) = annotations.bool("derive-gt") {
540 return x;
541 }
542 self.derive_gt
543 }
544 pub(crate) fn derive_gte(&self, annotations: &AnnotationSet) -> bool {
545 if let Some(x) = annotations.bool("derive-gte") {
546 return x;
547 }
548 self.derive_gte
549 }
550 pub(crate) fn derive_ostream(&self, annotations: &AnnotationSet) -> bool {
551 if let Some(x) = annotations.bool("derive-ostream") {
552 return x;
553 }
554 self.derive_ostream
555 }
556}
557
558#[derive(Debug, Clone, Deserialize)]
560#[serde(rename_all = "snake_case")]
561#[serde(deny_unknown_fields)]
562#[serde(default)]
563pub struct EnumConfig {
564 pub rename_variants: RenameRule,
566 pub rename_variant_name_fields: RenameRule,
570 pub add_sentinel: bool,
573 pub prefix_with_name: bool,
575 pub derive_helper_methods: bool,
578 pub derive_const_casts: bool,
580 pub derive_mut_casts: bool,
582 pub cast_assert_name: Option<String>,
586 pub must_use: Option<String>,
588 pub deprecated: Option<String>,
590 pub deprecated_with_note: Option<String>,
592 pub deprecated_variant: Option<String>,
594 pub deprecated_variant_with_note: Option<String>,
596 pub derive_tagged_enum_destructor: bool,
598 pub derive_tagged_enum_copy_constructor: bool,
600 pub derive_tagged_enum_copy_assignment: bool,
605 pub derive_ostream: bool,
607 pub enum_class: bool,
610 pub private_default_tagged_enum_constructor: bool,
613}
614
615impl Default for EnumConfig {
616 fn default() -> EnumConfig {
617 EnumConfig {
618 rename_variants: RenameRule::None,
619 rename_variant_name_fields: RenameRule::SnakeCase,
620 add_sentinel: false,
621 prefix_with_name: false,
622 derive_helper_methods: false,
623 derive_const_casts: false,
624 derive_mut_casts: false,
625 cast_assert_name: None,
626 must_use: None,
627 deprecated: None,
628 deprecated_with_note: None,
629 deprecated_variant: None,
630 deprecated_variant_with_note: None,
631 derive_tagged_enum_destructor: false,
632 derive_tagged_enum_copy_constructor: false,
633 derive_tagged_enum_copy_assignment: false,
634 derive_ostream: false,
635 enum_class: true,
636 private_default_tagged_enum_constructor: false,
637 }
638 }
639}
640
641impl EnumConfig {
642 pub(crate) fn add_sentinel(&self, annotations: &AnnotationSet) -> bool {
643 if let Some(x) = annotations.bool("add-sentinel") {
644 return x;
645 }
646 self.add_sentinel
647 }
648 pub(crate) fn derive_helper_methods(&self, annotations: &AnnotationSet) -> bool {
649 if let Some(x) = annotations.bool("derive-helper-methods") {
650 return x;
651 }
652 self.derive_helper_methods
653 }
654 pub(crate) fn derive_const_casts(&self, annotations: &AnnotationSet) -> bool {
655 if let Some(x) = annotations.bool("derive-const-casts") {
656 return x;
657 }
658 self.derive_const_casts
659 }
660 pub(crate) fn derive_mut_casts(&self, annotations: &AnnotationSet) -> bool {
661 if let Some(x) = annotations.bool("derive-mut-casts") {
662 return x;
663 }
664 self.derive_mut_casts
665 }
666 pub(crate) fn derive_tagged_enum_destructor(&self, annotations: &AnnotationSet) -> bool {
667 if let Some(x) = annotations.bool("derive-tagged-enum-destructor") {
668 return x;
669 }
670 self.derive_tagged_enum_destructor
671 }
672 pub(crate) fn derive_tagged_enum_copy_constructor(&self, annotations: &AnnotationSet) -> bool {
673 if let Some(x) = annotations.bool("derive-tagged-enum-copy-constructor") {
674 return x;
675 }
676 self.derive_tagged_enum_copy_constructor
677 }
678 pub(crate) fn derive_tagged_enum_copy_assignment(&self, annotations: &AnnotationSet) -> bool {
679 if let Some(x) = annotations.bool("derive-tagged-enum-copy-assignment") {
680 return x;
681 }
682 self.derive_tagged_enum_copy_assignment
683 }
684 pub(crate) fn derive_ostream(&self, annotations: &AnnotationSet) -> bool {
685 if let Some(x) = annotations.bool("derive-ostream") {
686 return x;
687 }
688 self.derive_ostream
689 }
690 pub(crate) fn enum_class(&self, annotations: &AnnotationSet) -> bool {
691 if let Some(x) = annotations.bool("enum-class") {
692 return x;
693 }
694 self.enum_class
695 }
696 pub(crate) fn private_default_tagged_enum_constructor(
697 &self,
698 annotations: &AnnotationSet,
699 ) -> bool {
700 if let Some(x) = annotations.bool("private-default-tagged-enum-constructor") {
701 return x;
702 }
703 self.private_default_tagged_enum_constructor
704 }
705}
706
707#[derive(Debug, Clone, Deserialize)]
709#[serde(rename_all = "snake_case")]
710#[serde(deny_unknown_fields)]
711#[serde(default)]
712pub struct ConstantConfig {
713 pub allow_static_const: bool,
715 pub allow_constexpr: bool,
717 pub sort_by: Option<SortKey>,
719}
720
721impl Default for ConstantConfig {
722 fn default() -> ConstantConfig {
723 ConstantConfig {
724 allow_static_const: true,
725 allow_constexpr: true,
726 sort_by: None,
727 }
728 }
729}
730
731#[derive(Debug, Clone, Deserialize, Default)]
733#[serde(rename_all = "snake_case")]
734#[serde(deny_unknown_fields)]
735#[serde(default)]
736pub struct MacroExpansionConfig {
737 pub bitflags: bool,
739}
740
741#[derive(Debug, Copy, Clone, PartialEq, Eq)]
743pub enum Profile {
744 Debug,
745 Release,
746}
747
748impl FromStr for Profile {
749 type Err = String;
750
751 fn from_str(s: &str) -> Result<Profile, Self::Err> {
752 match s {
753 "debug" | "Debug" => Ok(Profile::Debug),
754 "release" | "Release" => Ok(Profile::Release),
755 _ => Err(format!("Unrecognized Profile: '{}'.", s)),
756 }
757 }
758}
759
760deserialize_enum_str!(Profile);
761
762#[derive(Debug, Clone, Deserialize)]
764#[serde(rename_all = "snake_case")]
765#[serde(deny_unknown_fields)]
766#[serde(default)]
767pub struct ParseExpandConfig {
768 pub crates: Vec<String>,
770 pub all_features: bool,
772 pub default_features: bool,
774 pub features: Option<Vec<String>>,
777 pub profile: Profile,
779}
780
781impl Default for ParseExpandConfig {
782 fn default() -> ParseExpandConfig {
783 ParseExpandConfig {
784 crates: Vec::new(),
785 all_features: false,
786 default_features: true,
787 features: None,
788 profile: Profile::Debug,
789 }
790 }
791}
792
793fn retrocomp_parse_expand_config_deserialize<'de, D: Deserializer<'de>>(
801 deserializer: D,
802) -> Result<ParseExpandConfig, D::Error> {
803 struct ParseExpandVisitor;
804
805 impl<'de> Visitor<'de> for ParseExpandVisitor {
806 type Value = ParseExpandConfig;
807
808 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
809 formatter.write_str("a map or sequence of string")
810 }
811
812 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
813 let crates =
814 <Vec<String> as Deserialize>::deserialize(SeqAccessDeserializer::new(seq))?;
815 Ok(ParseExpandConfig {
816 crates,
817 all_features: true,
818 default_features: true,
819 features: None,
820 profile: Profile::Debug,
821 })
822 }
823
824 fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
825 <ParseExpandConfig as Deserialize>::deserialize(MapAccessDeserializer::new(map))
826 }
827 }
828
829 deserializer.deserialize_any(ParseExpandVisitor)
830}
831
832#[derive(Debug, Default, Clone, Deserialize)]
834#[serde(rename_all = "snake_case")]
835#[serde(deny_unknown_fields)]
836#[serde(default)]
837pub struct ParseConfig {
838 pub parse_deps: bool,
847 pub include: Option<Vec<String>>,
849 pub exclude: Vec<String>,
851 #[serde(deserialize_with = "retrocomp_parse_expand_config_deserialize")]
853 pub expand: ParseExpandConfig,
854 pub clean: bool,
857 pub extra_bindings: Vec<String>,
860}
861
862impl ParseConfig {
863 pub(crate) fn should_generate_top_level_item(
864 &self,
865 crate_name: &str,
866 binding_crate_name: &str,
867 ) -> bool {
868 if crate_name == binding_crate_name {
869 return true;
871 }
872
873 self.extra_bindings.iter().any(|dep| dep == crate_name)
874 }
875}
876
877#[derive(Debug, Clone, Default, Deserialize)]
879#[serde(rename_all = "snake_case")]
880#[serde(deny_unknown_fields)]
881#[serde(default)]
882pub struct PtrConfig {
883 pub non_null_attribute: Option<String>,
885}
886
887#[derive(Debug, Clone, Default, Deserialize)]
889#[serde(rename_all = "snake_case")]
890#[serde(deny_unknown_fields)]
891#[serde(default)]
892pub struct CythonConfig {
893 pub header: Option<String>,
895 pub cimports: BTreeMap<String, Vec<String>>,
898}
899
900#[derive(Debug, Clone, Deserialize)]
902#[serde(rename_all = "snake_case")]
903#[serde(deny_unknown_fields)]
904#[serde(default)]
905pub struct Config {
906 pub header: Option<String>,
908 pub includes: Vec<String>,
910 pub sys_includes: Vec<String>,
912 pub after_includes: Option<String>,
914 pub trailer: Option<String>,
916 pub include_guard: Option<String>,
918 pub pragma_once: bool,
920 pub no_includes: bool,
925 pub package_version: bool,
927 pub autogen_warning: Option<String>,
929 pub include_version: bool,
931 pub namespace: Option<String>,
933 pub namespaces: Option<Vec<String>>,
935 pub using_namespaces: Option<Vec<String>>,
937 pub braces: Braces,
939 pub line_length: usize,
941 pub tab_width: usize,
943 pub line_endings: LineEndingStyle,
945 pub language: Language,
947 pub cpp_compat: bool,
949 pub style: Style,
951 pub sort_by: SortKey,
953 pub usize_is_size_t: bool,
956 pub parse: ParseConfig,
958 pub export: ExportConfig,
960 pub macro_expansion: MacroExpansionConfig,
962 pub layout: LayoutConfig,
964 #[serde(rename = "fn")]
966 pub function: FunctionConfig,
967 #[serde(rename = "struct")]
969 pub structure: StructConfig,
970 #[serde(rename = "enum")]
972 pub enumeration: EnumConfig,
973 #[serde(rename = "const")]
975 pub constant: ConstantConfig,
976 pub defines: HashMap<String, String>,
978 pub documentation: bool,
980 pub documentation_style: DocumentationStyle,
982 pub documentation_length: DocumentationLength,
984 #[serde(rename = "ptr")]
986 pub pointer: PtrConfig,
987 pub only_target_dependencies: bool,
1022 pub cython: CythonConfig,
1024 #[doc(hidden)]
1025 #[serde(skip)]
1026 pub config_path: Option<StdPathBuf>,
1033}
1034
1035impl Default for Config {
1036 fn default() -> Config {
1037 Config {
1038 header: None,
1039 includes: Vec::new(),
1040 sys_includes: Vec::new(),
1041 after_includes: None,
1042 trailer: None,
1043 include_guard: None,
1044 pragma_once: false,
1045 autogen_warning: None,
1046 include_version: false,
1047 no_includes: false,
1048 package_version: false,
1049 namespace: None,
1050 namespaces: None,
1051 using_namespaces: None,
1052 braces: Braces::SameLine,
1053 line_length: 100,
1054 tab_width: 2,
1055 line_endings: LineEndingStyle::default(),
1056 language: Language::Cxx,
1057 cpp_compat: false,
1058 style: Style::default(),
1059 usize_is_size_t: false,
1060 sort_by: SortKey::None,
1061 macro_expansion: Default::default(),
1062 parse: ParseConfig::default(),
1063 export: ExportConfig::default(),
1064 layout: LayoutConfig::default(),
1065 function: FunctionConfig::default(),
1066 structure: StructConfig::default(),
1067 enumeration: EnumConfig::default(),
1068 constant: ConstantConfig::default(),
1069 defines: HashMap::new(),
1070 documentation: true,
1071 documentation_style: DocumentationStyle::Auto,
1072 documentation_length: DocumentationLength::Full,
1073 pointer: PtrConfig::default(),
1074 only_target_dependencies: false,
1075 cython: CythonConfig::default(),
1076 config_path: None,
1077 }
1078 }
1079}
1080
1081impl Config {
1082 pub(crate) fn cpp_compatible_c(&self) -> bool {
1083 self.language == Language::C && self.cpp_compat
1084 }
1085
1086 pub(crate) fn include_guard(&self) -> Option<&str> {
1087 if self.language == Language::Cython {
1088 None
1089 } else {
1090 self.include_guard.as_deref()
1091 }
1092 }
1093
1094 pub(crate) fn includes(&self) -> &[String] {
1095 if self.language == Language::Cython {
1096 &[]
1097 } else {
1098 &self.includes
1099 }
1100 }
1101
1102 pub(crate) fn sys_includes(&self) -> &[String] {
1103 if self.language == Language::Cython {
1104 &[]
1105 } else {
1106 &self.sys_includes
1107 }
1108 }
1109
1110 pub fn from_file<P: AsRef<StdPath>>(file_name: P) -> Result<Config, String> {
1111 let config_text = fs::read_to_string(file_name.as_ref()).map_err(|_| {
1112 format!(
1113 "Couldn't open config file: {}.",
1114 file_name.as_ref().display()
1115 )
1116 })?;
1117
1118 let mut config = toml::from_str::<Config>(&config_text)
1119 .map_err(|e| format!("Couldn't parse config file: {}.", e))?;
1120 config.config_path = Some(StdPathBuf::from(file_name.as_ref()));
1121 Ok(config)
1122 }
1123
1124 pub fn from_root_or_default<P: AsRef<StdPath>>(root: P) -> Config {
1125 let c = root.as_ref().join("cbindgen.toml");
1126
1127 if c.exists() {
1128 Config::from_file(c).unwrap()
1129 } else {
1130 Config::default()
1131 }
1132 }
1133}