| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame^] | 1 | use crate::gen::out::{Content, OutFile}; |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 2 | use crate::syntax::{self, IncludeKind}; |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 3 | use std::ops::{Deref, DerefMut}; |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 4 | |
| David Tolnay | 0e01d64 | 2020-10-16 12:54:44 -0700 | [diff] [blame] | 5 | /// The complete contents of the "rust/cxx.h" header. |
| David Tolnay | 736cbca | 2020-03-11 16:49:18 -0700 | [diff] [blame] | 6 | pub static HEADER: &str = include_str!("include/cxx.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 8 | /// 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 Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 13 | pub struct Include { |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 14 | /// The header's path, not including the enclosing quotation marks or angle |
| 15 | /// brackets. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 16 | pub path: String, |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 17 | /// Whether to emit `#include "path"` or `#include <path>`. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 18 | pub kind: IncludeKind, |
| 19 | } |
| 20 | |
| David Tolnay | 3577d45 | 2020-03-17 21:48:13 -0700 | [diff] [blame] | 21 | #[derive(Default, PartialEq)] |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 22 | pub struct Includes { |
| David Tolnay | 12af7e4 | 2020-10-31 21:09:23 -0700 | [diff] [blame] | 23 | pub custom: Vec<Include>, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 24 | pub array: bool, |
| David Tolnay | 30430f1 | 2020-03-19 20:49:00 -0700 | [diff] [blame] | 25 | pub cstddef: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 26 | pub cstdint: bool, |
| David Tolnay | ebef4a2 | 2020-03-17 15:33:47 -0700 | [diff] [blame] | 27 | pub cstring: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 28 | pub exception: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 29 | pub memory: bool, |
| David Tolnay | 0ecd05a | 2020-07-29 16:32:03 -0700 | [diff] [blame] | 30 | pub new: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 31 | pub string: bool, |
| 32 | pub type_traits: bool, |
| David Tolnay | 4791f1c | 2020-03-17 21:53:16 -0700 | [diff] [blame] | 33 | pub utility: bool, |
| David Tolnay | 8b7f899 | 2020-04-25 13:06:08 -0700 | [diff] [blame] | 34 | pub vector: bool, |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 35 | pub basetsd: bool, |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 36 | pub content: Content, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | impl Includes { |
| 40 | pub fn new() -> Self { |
| 41 | Includes::default() |
| 42 | } |
| 43 | |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 44 | pub fn insert(&mut self, include: impl Into<Include>) { |
| 45 | self.custom.push(include.into()); |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 46 | } |
| 47 | } |
| 48 | |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame^] | 49 | pub(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 Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 104 | impl<'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 Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 107 | } |
| 108 | } |
| 109 | |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 110 | impl<'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 Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 118 | |
| 119 | impl Deref for Includes { |
| 120 | type Target = Content; |
| 121 | |
| 122 | fn deref(&self) -> &Self::Target { |
| 123 | &self.content |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | impl DerefMut for Includes { |
| 128 | fn deref_mut(&mut self) -> &mut Self::Target { |
| 129 | &mut self.content |
| 130 | } |
| 131 | } |