1pub trait Platform {
5 fn defines(&self) -> &[&str];
6 fn standards(&self) -> &Standards<'_>;
7}
8
9pub trait ConstPlatform {
11 const DEFINES: &'static [&'static str];
12 const STANDARDS: Standards<'static> = Standards {
13 gnu: Some("gnu99"),
14 clang: Some("gnu99"),
15 msvc: Some("c99"),
16 clang_cl: Some("gnu99"),
17 };
18}
19impl<T: ConstPlatform> Platform for T {
20 fn defines(&self) -> &[&str] {
21 Self::DEFINES
22 }
23 fn standards(&self) -> &Standards<'_> {
24 &Self::STANDARDS
25 }
26}
27
28macro_rules! platform {
29 {
30 $(#[$attr:meta])*
31 $vis:vis struct $name:ident;
32 DEFINES = $defines:expr;
33 $(STANDARDS = $standards:expr;)?
34 } => {
35 #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
36 $(#[$attr])*
37 $vis struct $name;
38
39 impl ConstPlatform for $name {
40 const DEFINES: &[&str] = $defines;
41 $(const STANDARDS: Standards<'_> = $standards;)?
42 }
43 };
44}
45
46platform! {
47 pub struct Aix;
48 DEFINES = &[
49 "LUA_USE_POSIX",
50 "LUA_USE_DLOPEN",
51 ];
52}
53
54platform! {
55 pub struct Bsd;
56 DEFINES = &[
57 "LUA_USE_POSIX",
58 "LUA_USE_DLOPEN",
59 ];
60}
61
62platform! {
63 pub struct C89;
64 DEFINES = &[
65 "LUA_USE_POSIX",
66 "LUA_USE_DLOPEN",
67 ];
68 STANDARDS = Standards {
69 gnu: Some("c89"),
70 clang: Some("c89"),
71 msvc: None,
72 clang_cl: Some("c89"),
73 };
74}
75
76platform! {
77 pub struct FreeBsd;
78 DEFINES = &[
79 "LUA_USE_LINUX",
80 ];
81}
82
83platform! {
84 pub struct Ios;
85 DEFINES = &[
86 "LUA_USE_IOS",
87 ];
88}
89
90platform! {
91 pub struct Linux;
92 DEFINES = &[
93 "LUA_USE_LINUX",
94 ];
95}
96
97platform! {
98 pub struct MacOsX;
99 DEFINES = &[
100 "LUA_USE_MACOSX",
101 ];
102}
103
104platform! {
105 pub struct MinGw;
106 DEFINES = &[
107 "LUA_BUILD_AS_DLL",
108 ];
109}
110
111platform! {
112 pub struct Posix;
113 DEFINES = &[
114 "LUA_USE_POSIX",
115 ];
116}
117
118platform! {
119 pub struct Solaris;
120 DEFINES = &[
121 "LUA_USE_POSIX",
122 "LUA_USE_DLOPEN",
123 "_REENTRANT",
124 ];
125}
126
127platform! {
128 pub struct Windows;
129 DEFINES = &[
130 "LUA_USE_WINDOWS",
131 ];
132}
133
134#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
136pub struct Standards<'a> {
137 pub gnu: Option<&'a str>,
138 pub clang: Option<&'a str>,
139 pub msvc: Option<&'a str>,
140 pub clang_cl: Option<&'a str>,
141}
142
143struct DynPlatform {
144 pub defines: &'static [&'static str],
145 pub standards: &'static Standards<'static>,
146}
147
148impl DynPlatform {
149 pub const fn new<P: ConstPlatform>() -> Self {
151 Self {
152 defines: P::DEFINES,
153 standards: &P::STANDARDS,
154 }
155 }
156}
157
158impl Platform for DynPlatform {
159 fn defines(&self) -> &[&str] {
160 self.defines
161 }
162 fn standards(&self) -> &Standards<'_> {
163 self.standards
164 }
165}
166
167pub const CURRENT_TRIPLE: &str = current_platform::CURRENT_PLATFORM;
169
170pub fn from_current_triple() -> Option<impl Platform> {
172 from_target_triple(CURRENT_TRIPLE)
173}
174
175pub fn from_target_triple(target: &str) -> Option<impl Platform> {
177 if target.contains("linux") {
178 Some(DynPlatform::new::<Linux>())
179 } else if target.ends_with("bsd") {
180 Some(DynPlatform::new::<FreeBsd>())
181 } else if target.ends_with("apple-darwin") {
182 Some(DynPlatform::new::<MacOsX>())
183 } else if target.ends_with("apple-ios") {
184 Some(DynPlatform::new::<Ios>())
185 } else if target.ends_with("solaris") {
186 Some(DynPlatform::new::<Solaris>())
187 } else if target.contains("windows") {
188 Some(DynPlatform::new::<Windows>())
189 } else {
190 None
191 }
192}