blob: 8dc7146dfcc22749057d71cee847ae528da0bfcf [file] [log] [blame]
David Tolnay2f3e90b2020-10-31 22:16:51 -07001use crate::gen::out::{Content, OutFile};
David Tolnay353d98c2020-10-28 15:43:35 -07002use crate::syntax::{self, IncludeKind};
David Tolnay8810a542020-10-31 21:39:22 -07003use std::ops::{Deref, DerefMut};
David Tolnay9c68b1a2020-03-06 11:12:55 -08004
David Tolnay0e01d642020-10-16 12:54:44 -07005/// The complete contents of the "rust/cxx.h" header.
David Tolnay736cbca2020-03-11 16:49:18 -07006pub static HEADER: &str = include_str!("include/cxx.h");
David Tolnay7db73692019-10-20 14:51:12 -04007
David Tolnay700cd0c2020-10-28 12:40:27 -07008/// A header to #include.
9///
10/// The cxxbridge tool does not parse or even require the given paths to exist;
11/// they simply go into the generated C++ code as #include lines.
12#[derive(Clone, PartialEq, Debug)]
David Tolnay4aae7c02020-10-28 12:35:42 -070013pub struct Include {
David Tolnay700cd0c2020-10-28 12:40:27 -070014 /// The header's path, not including the enclosing quotation marks or angle
15 /// brackets.
David Tolnay4aae7c02020-10-28 12:35:42 -070016 pub path: String,
David Tolnay700cd0c2020-10-28 12:40:27 -070017 /// Whether to emit `#include "path"` or `#include <path>`.
David Tolnay4aae7c02020-10-28 12:35:42 -070018 pub kind: IncludeKind,
19}
20
David Tolnay3577d452020-03-17 21:48:13 -070021#[derive(Default, PartialEq)]
David Tolnay9c68b1a2020-03-06 11:12:55 -080022pub struct Includes {
David Tolnay12af7e42020-10-31 21:09:23 -070023 pub custom: Vec<Include>,
David Tolnayb7a7cb62020-03-17 21:18:40 -070024 pub array: bool,
David Tolnay30430f12020-03-19 20:49:00 -070025 pub cstddef: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080026 pub cstdint: bool,
David Tolnayebef4a22020-03-17 15:33:47 -070027 pub cstring: bool,
David Tolnayb7a7cb62020-03-17 21:18:40 -070028 pub exception: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080029 pub memory: bool,
David Tolnay0ecd05a2020-07-29 16:32:03 -070030 pub new: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080031 pub string: bool,
32 pub type_traits: bool,
David Tolnay4791f1c2020-03-17 21:53:16 -070033 pub utility: bool,
David Tolnay8b7f8992020-04-25 13:06:08 -070034 pub vector: bool,
David Tolnayda38b7c2020-09-16 11:50:04 -040035 pub basetsd: bool,
David Tolnay8810a542020-10-31 21:39:22 -070036 pub content: Content,
David Tolnay9c68b1a2020-03-06 11:12:55 -080037}
38
39impl Includes {
40 pub fn new() -> Self {
41 Includes::default()
42 }
43
David Tolnay353d98c2020-10-28 15:43:35 -070044 pub fn insert(&mut self, include: impl Into<Include>) {
45 self.custom.push(include.into());
David Tolnay9c68b1a2020-03-06 11:12:55 -080046 }
47}
48
David Tolnay2f3e90b2020-10-31 22:16:51 -070049pub(super) fn write(out: &mut OutFile) {
50 let include = &mut out.include;
51 let out = &mut include.content;
52
53 for include in &include.custom {
54 match include.kind {
55 IncludeKind::Quoted => {
56 writeln!(out, "#include \"{}\"", include.path.escape_default());
57 }
58 IncludeKind::Bracketed => {
59 writeln!(out, "#include <{}>", include.path);
60 }
61 }
62 }
63
64 if include.array {
65 writeln!(out, "#include <array>");
66 }
67 if include.cstddef {
68 writeln!(out, "#include <cstddef>");
69 }
70 if include.cstdint {
71 writeln!(out, "#include <cstdint>");
72 }
73 if include.cstring {
74 writeln!(out, "#include <cstring>");
75 }
76 if include.exception {
77 writeln!(out, "#include <exception>");
78 }
79 if include.memory {
80 writeln!(out, "#include <memory>");
81 }
82 if include.new {
83 writeln!(out, "#include <new>");
84 }
85 if include.string {
86 writeln!(out, "#include <string>");
87 }
88 if include.type_traits {
89 writeln!(out, "#include <type_traits>");
90 }
91 if include.utility {
92 writeln!(out, "#include <utility>");
93 }
94 if include.vector {
95 writeln!(out, "#include <vector>");
96 }
97 if include.basetsd {
98 writeln!(out, "#if defined(_WIN32)");
99 writeln!(out, "#include <basetsd.h>");
100 writeln!(out, "#endif");
101 }
102}
103
David Tolnay700cd0c2020-10-28 12:40:27 -0700104impl<'a> Extend<&'a Include> for Includes {
105 fn extend<I: IntoIterator<Item = &'a Include>>(&mut self, iter: I) {
106 self.custom.extend(iter.into_iter().cloned());
David Tolnay33d30292020-03-18 18:02:02 -0700107 }
108}
109
David Tolnay353d98c2020-10-28 15:43:35 -0700110impl<'a> From<&'a syntax::Include> for Include {
111 fn from(include: &syntax::Include) -> Self {
112 Include {
113 path: include.path.clone(),
114 kind: include.kind,
115 }
116 }
117}
David Tolnay8810a542020-10-31 21:39:22 -0700118
119impl Deref for Includes {
120 type Target = Content;
121
122 fn deref(&self) -> &Self::Target {
123 &self.content
124 }
125}
126
127impl DerefMut for Includes {
128 fn deref_mut(&mut self) -> &mut Self::Target {
129 &mut self.content
130 }
131}