1use crate::gen::out::{Content, OutFile};
2use crate::syntax::{self, IncludeKind};
3use std::ops::{Deref, DerefMut};
4
5;
7
8)]
13pub struct Include {
14 pub path: String,
17 pub kind: IncludeKind,
19}
20
21#[derive(#[automatically_derived]
impl<'a> ::core::default::Default for Includes<'a> {
#[inline]
fn default() -> Includes<'a> {
Includes {
custom: ::core::default::Default::default(),
algorithm: ::core::default::Default::default(),
array: ::core::default::Default::default(),
cassert: ::core::default::Default::default(),
cstddef: ::core::default::Default::default(),
cstdint: ::core::default::Default::default(),
cstring: ::core::default::Default::default(),
exception: ::core::default::Default::default(),
functional: ::core::default::Default::default(),
initializer_list: ::core::default::Default::default(),
iterator: ::core::default::Default::default(),
limits: ::core::default::Default::default(),
memory: ::core::default::Default::default(),
new: ::core::default::Default::default(),
ranges: ::core::default::Default::default(),
stdexcept: ::core::default::Default::default(),
string: ::core::default::Default::default(),
string_view: ::core::default::Default::default(),
type_traits: ::core::default::Default::default(),
utility: ::core::default::Default::default(),
vector: ::core::default::Default::default(),
basetsd: ::core::default::Default::default(),
sys_types: ::core::default::Default::default(),
content: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for Includes<'a> {
#[inline]
fn eq(&self, other: &Includes<'a>) -> bool {
self.algorithm == other.algorithm && self.array == other.array &&
self.cassert == other.cassert &&
self.cstddef == other.cstddef &&
self.cstdint == other.cstdint &&
self.cstring == other.cstring &&
self.exception == other.exception &&
self.functional == other.functional &&
self.initializer_list == other.initializer_list &&
self.iterator == other.iterator &&
self.limits == other.limits && self.memory == other.memory
&& self.new == other.new && self.ranges == other.ranges &&
self.stdexcept == other.stdexcept &&
self.string == other.string &&
self.string_view == other.string_view &&
self.type_traits == other.type_traits &&
self.utility == other.utility && self.vector == other.vector
&& self.basetsd == other.basetsd &&
self.sys_types == other.sys_types &&
self.custom == other.custom && self.content == other.content
}
}PartialEq)]
22pub(crate) struct Includes<'a> {
23 pub custom: Vec<Include>,
24 pub algorithm: bool,
25 pub array: bool,
26 pub cassert: bool,
27 pub cstddef: bool,
28 pub cstdint: bool,
29 pub cstring: bool,
30 pub exception: bool,
31 pub functional: bool,
32 pub initializer_list: bool,
33 pub iterator: bool,
34 pub limits: bool,
35 pub memory: bool,
36 pub new: bool,
37 pub ranges: bool,
38 pub stdexcept: bool,
39 pub string: bool,
40 pub string_view: bool,
41 pub type_traits: bool,
42 pub utility: bool,
43 pub vector: bool,
44 pub basetsd: bool,
45 pub sys_types: bool,
46 pub content: Content<'a>,
47}
48
49impl<'a> Includes<'a> {
50 pub(crate) fn new() -> Self {
51 Includes::default()
52 }
53
54 pub(crate) fn insert(&mut self, include: impl Into<Include>) {
55 self.custom.push(include.into());
56 }
57
58 pub(crate) fn has_cxx_header(&self) -> bool {
59 self.custom
60 .iter()
61 .any(|header| header.path == "rust/cxx.h" || header.path == "rust\\cxx.h")
62 }
63}
64
65pub(super) fn write(out: &mut OutFile) {
66 let header = out.header;
67 let include = &mut out.include;
68 let cxx_header = include.has_cxx_header();
69 let out = &mut include.content;
70
71 if header {
72 out.write_fmt(format_args!("#pragma once\n"));writeln!(out, "#pragma once");
73 }
74
75 for include in &include.custom {
76 match include.kind {
77 IncludeKind::Quoted => {
78 out.write_fmt(format_args!("#include \"{0}\"\n",
include.path.escape_default()));writeln!(out, "#include \"{}\"", include.path.escape_default());
79 }
80 IncludeKind::Bracketed => {
81 out.write_fmt(format_args!("#include <{0}>\n", include.path));writeln!(out, "#include <{}>", include.path);
82 }
83 }
84 }
85
86 let Includes {
87 custom: _,
88 algorithm,
89 array,
90 cassert,
91 cstddef,
92 cstdint,
93 cstring,
94 exception,
95 functional,
96 initializer_list,
97 iterator,
98 limits,
99 memory,
100 new,
101 ranges,
102 stdexcept,
103 string,
104 string_view,
105 type_traits,
106 utility,
107 vector,
108 basetsd,
109 sys_types,
110 content: _,
111 } = *include;
112
113 if algorithm && !cxx_header {
114 out.write_fmt(format_args!("#include <algorithm>\n"));writeln!(out, "#include <algorithm>");
115 }
116 if array && !cxx_header {
117 out.write_fmt(format_args!("#include <array>\n"));writeln!(out, "#include <array>");
118 }
119 if cassert && !cxx_header {
120 out.write_fmt(format_args!("#include <cassert>\n"));writeln!(out, "#include <cassert>");
121 }
122 if cstddef && !cxx_header {
123 out.write_fmt(format_args!("#include <cstddef>\n"));writeln!(out, "#include <cstddef>");
124 }
125 if cstdint && !cxx_header {
126 out.write_fmt(format_args!("#include <cstdint>\n"));writeln!(out, "#include <cstdint>");
127 }
128 if cstring {
129 out.write_fmt(format_args!("#include <cstring>\n"));writeln!(out, "#include <cstring>");
130 }
131 if exception && !cxx_header {
132 out.write_fmt(format_args!("#include <exception>\n"));writeln!(out, "#include <exception>");
133 }
134 if functional {
135 out.write_fmt(format_args!("#include <functional>\n"));writeln!(out, "#include <functional>");
136 }
137 if initializer_list && !cxx_header {
138 out.write_fmt(format_args!("#include <initializer_list>\n"));writeln!(out, "#include <initializer_list>");
139 }
140 if iterator && !cxx_header {
141 out.write_fmt(format_args!("#include <iterator>\n"));writeln!(out, "#include <iterator>");
142 }
143 if limits {
144 out.write_fmt(format_args!("#include <limits>\n"));writeln!(out, "#include <limits>");
145 }
146 if memory {
147 out.write_fmt(format_args!("#include <memory>\n"));writeln!(out, "#include <memory>");
148 }
149 if new && !cxx_header {
150 out.write_fmt(format_args!("#include <new>\n"));writeln!(out, "#include <new>");
151 }
152 if stdexcept && !cxx_header {
153 out.write_fmt(format_args!("#include <stdexcept>\n"));writeln!(out, "#include <stdexcept>");
154 }
155 if string && !cxx_header {
156 out.write_fmt(format_args!("#include <string>\n"));writeln!(out, "#include <string>");
157 }
158 if type_traits && !cxx_header {
159 out.write_fmt(format_args!("#include <type_traits>\n"));writeln!(out, "#include <type_traits>");
160 }
161 if utility && !cxx_header {
162 out.write_fmt(format_args!("#include <utility>\n"));writeln!(out, "#include <utility>");
163 }
164 if vector && !cxx_header {
165 out.write_fmt(format_args!("#include <vector>\n"));writeln!(out, "#include <vector>");
166 }
167 if basetsd && !cxx_header {
168 out.write_fmt(format_args!("#if defined(_WIN32)\n"));writeln!(out, "#if defined(_WIN32)");
169 out.write_fmt(format_args!("#include <basetsd.h>\n"));writeln!(out, "#include <basetsd.h>");
170 }
171 if sys_types && !cxx_header {
172 if basetsd {
173 out.write_fmt(format_args!("#else\n"));writeln!(out, "#else");
174 } else {
175 out.write_fmt(format_args!("#if not defined(_WIN32)\n"));writeln!(out, "#if not defined(_WIN32)");
176 }
177 }
178 if sys_types && !cxx_header {
179 out.write_fmt(format_args!("#include <sys/types.h>\n"));writeln!(out, "#include <sys/types.h>");
180 }
181 if (basetsd || sys_types) && !cxx_header {
182 out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
183 }
184 if string_view && !cxx_header {
185 out.write_fmt(format_args!("#if __cplusplus >= 201703L\n"));writeln!(out, "#if __cplusplus >= 201703L");
186 out.write_fmt(format_args!("#include <string_view>\n"));writeln!(out, "#include <string_view>");
187 out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
188 }
189 if ranges && !cxx_header {
190 out.write_fmt(format_args!("#if __cplusplus >= 202002L\n"));writeln!(out, "#if __cplusplus >= 202002L");
191 out.write_fmt(format_args!("#include <ranges>\n"));writeln!(out, "#include <ranges>");
192 out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
193 }
194}
195
196impl<'i, 'a> Extend<&'i Include> for Includes<'a> {
197 fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) {
198 self.custom.extend(iter.into_iter().cloned());
199 }
200}
201
202impl From<&syntax::Include> for Include {
203 fn from(include: &syntax::Include) -> Self {
204 Include {
205 path: include.path.clone(),
206 kind: include.kind,
207 }
208 }
209}
210
211impl<'a> Deref for Includes<'a> {
212 type Target = Content<'a>;
213
214 fn deref(&self) -> &Self::Target {
215 &self.content
216 }
217}
218
219impl<'a> DerefMut for Includes<'a> {
220 fn deref_mut(&mut self) -> &mut Self::Target {
221 &mut self.content
222 }
223}