blob: 9db95be18b6eb1917a02f68b162a049a19ee86a2 [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 Tolnay97c5b862020-11-01 14:59:01 -080022pub struct Includes<'a> {
David Tolnay12af7e42020-10-31 21:09:23 -070023 pub custom: Vec<Include>,
David Tolnayf799b372020-11-29 23:57:42 -080024 pub algorithm: bool,
David Tolnayb7a7cb62020-03-17 21:18:40 -070025 pub array: bool,
David Tolnay30430f12020-03-19 20:49:00 -070026 pub cstddef: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080027 pub cstdint: bool,
David Tolnayebef4a22020-03-17 15:33:47 -070028 pub cstring: bool,
David Tolnayb7a7cb62020-03-17 21:18:40 -070029 pub exception: bool,
David Tolnayf799b372020-11-29 23:57:42 -080030 pub initializer_list: bool,
David Tolnayd1df4c72020-11-25 20:38:05 -080031 pub iterator: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080032 pub memory: bool,
David Tolnay0ecd05a2020-07-29 16:32:03 -070033 pub new: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080034 pub string: bool,
35 pub type_traits: bool,
David Tolnay4791f1c2020-03-17 21:53:16 -070036 pub utility: bool,
David Tolnay8b7f8992020-04-25 13:06:08 -070037 pub vector: bool,
David Tolnayda38b7c2020-09-16 11:50:04 -040038 pub basetsd: bool,
David Tolnay97c5b862020-11-01 14:59:01 -080039 pub content: Content<'a>,
David Tolnay9c68b1a2020-03-06 11:12:55 -080040}
41
David Tolnay97c5b862020-11-01 14:59:01 -080042impl<'a> Includes<'a> {
David Tolnay9c68b1a2020-03-06 11:12:55 -080043 pub fn new() -> Self {
44 Includes::default()
45 }
46
David Tolnay353d98c2020-10-28 15:43:35 -070047 pub fn insert(&mut self, include: impl Into<Include>) {
48 self.custom.push(include.into());
David Tolnay9c68b1a2020-03-06 11:12:55 -080049 }
50}
51
David Tolnay2f3e90b2020-10-31 22:16:51 -070052pub(super) fn write(out: &mut OutFile) {
David Tolnay58711a92020-11-01 19:11:37 -080053 let header = out.header;
David Tolnay2f3e90b2020-10-31 22:16:51 -070054 let include = &mut out.include;
55 let out = &mut include.content;
56
David Tolnay58711a92020-11-01 19:11:37 -080057 if header {
58 writeln!(out, "#pragma once");
59 }
60
David Tolnay2f3e90b2020-10-31 22:16:51 -070061 for include in &include.custom {
62 match include.kind {
63 IncludeKind::Quoted => {
64 writeln!(out, "#include \"{}\"", include.path.escape_default());
65 }
66 IncludeKind::Bracketed => {
67 writeln!(out, "#include <{}>", include.path);
68 }
69 }
70 }
71
David Tolnaya829be62020-11-25 20:41:12 -080072 let Includes {
73 custom: _,
David Tolnayf799b372020-11-29 23:57:42 -080074 algorithm,
David Tolnaya829be62020-11-25 20:41:12 -080075 array,
76 cstddef,
77 cstdint,
78 cstring,
79 exception,
David Tolnayf799b372020-11-29 23:57:42 -080080 initializer_list,
David Tolnaya829be62020-11-25 20:41:12 -080081 iterator,
82 memory,
83 new,
84 string,
85 type_traits,
86 utility,
87 vector,
88 basetsd,
89 content: _,
90 } = *include;
91
David Tolnayf799b372020-11-29 23:57:42 -080092 if algorithm {
93 writeln!(out, "#include <algorithm>");
94 }
David Tolnaya829be62020-11-25 20:41:12 -080095 if array {
David Tolnay2f3e90b2020-10-31 22:16:51 -070096 writeln!(out, "#include <array>");
97 }
David Tolnaya829be62020-11-25 20:41:12 -080098 if cstddef {
David Tolnay2f3e90b2020-10-31 22:16:51 -070099 writeln!(out, "#include <cstddef>");
100 }
David Tolnaya829be62020-11-25 20:41:12 -0800101 if cstdint {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700102 writeln!(out, "#include <cstdint>");
103 }
David Tolnaya829be62020-11-25 20:41:12 -0800104 if cstring {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700105 writeln!(out, "#include <cstring>");
106 }
David Tolnaya829be62020-11-25 20:41:12 -0800107 if exception {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700108 writeln!(out, "#include <exception>");
109 }
David Tolnayf799b372020-11-29 23:57:42 -0800110 if initializer_list {
111 writeln!(out, "#include <initializer_list>");
112 }
David Tolnaya829be62020-11-25 20:41:12 -0800113 if iterator {
David Tolnayd1df4c72020-11-25 20:38:05 -0800114 writeln!(out, "#include <iterator>");
115 }
David Tolnaya829be62020-11-25 20:41:12 -0800116 if memory {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700117 writeln!(out, "#include <memory>");
118 }
David Tolnaya829be62020-11-25 20:41:12 -0800119 if new {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700120 writeln!(out, "#include <new>");
121 }
David Tolnaya829be62020-11-25 20:41:12 -0800122 if string {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700123 writeln!(out, "#include <string>");
124 }
David Tolnaya829be62020-11-25 20:41:12 -0800125 if type_traits {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700126 writeln!(out, "#include <type_traits>");
127 }
David Tolnaya829be62020-11-25 20:41:12 -0800128 if utility {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700129 writeln!(out, "#include <utility>");
130 }
David Tolnaya829be62020-11-25 20:41:12 -0800131 if vector {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700132 writeln!(out, "#include <vector>");
133 }
David Tolnaya829be62020-11-25 20:41:12 -0800134 if basetsd {
David Tolnay2f3e90b2020-10-31 22:16:51 -0700135 writeln!(out, "#if defined(_WIN32)");
136 writeln!(out, "#include <basetsd.h>");
137 writeln!(out, "#endif");
138 }
139}
140
David Tolnay97c5b862020-11-01 14:59:01 -0800141impl<'i, 'a> Extend<&'i Include> for Includes<'a> {
142 fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) {
David Tolnay700cd0c2020-10-28 12:40:27 -0700143 self.custom.extend(iter.into_iter().cloned());
David Tolnay33d30292020-03-18 18:02:02 -0700144 }
145}
146
David Tolnay97c5b862020-11-01 14:59:01 -0800147impl<'i> From<&'i syntax::Include> for Include {
David Tolnay353d98c2020-10-28 15:43:35 -0700148 fn from(include: &syntax::Include) -> Self {
149 Include {
150 path: include.path.clone(),
151 kind: include.kind,
152 }
153 }
154}
David Tolnay8810a542020-10-31 21:39:22 -0700155
David Tolnay97c5b862020-11-01 14:59:01 -0800156impl<'a> Deref for Includes<'a> {
157 type Target = Content<'a>;
David Tolnay8810a542020-10-31 21:39:22 -0700158
159 fn deref(&self) -> &Self::Target {
160 &self.content
161 }
162}
163
David Tolnay97c5b862020-11-01 14:59:01 -0800164impl<'a> DerefMut for Includes<'a> {
David Tolnay8810a542020-10-31 21:39:22 -0700165 fn deref_mut(&mut self) -> &mut Self::Target {
166 &mut self.content
167 }
168}