target_tuples/
lib.rs

1#![deny(warnings, unsafe_code)]
2#![cfg_attr(not(any(doc, test)), no_std)]
3
4extern crate alloc;
5
6mod pieces;
7
8pub use pieces::*;
9
10#[doc(hidden)]
11#[macro_export]
12macro_rules! __to_target {
13    ($first:ident-$($rest:ident)-+) => {
14        ::core::concat!(::core::stringify!($first) $(,"-",::core::stringify!($rest))*)
15    }
16}
17
18#[doc(hidden)]
19#[macro_export]
20macro_rules! __match_target_pattern {
21    ($arch:ident-$vendor:ident-$os:ident-$env:ident) => {{
22        fn __check(targ: &$crate::Target) -> bool {
23            let mtarg = $crate::Target::parse($crate::__to_target!($arch - $vendor - $os - $env));
24            *targ == mtarg
25        }
26
27        __check
28    }};
29
30    ($arch:ident-$vendor:ident-$sys:ident) => {{
31        fn __check(targ: &$crate::Target) -> bool {
32            let mtarg = $crate::Target::parse($crate::__to_target!($arch - $vendor - $sys));
33            targ == mtarg
34        }
35
36        __check
37    }};
38
39    (*-$vendor:ident-$os:ident-$env:ident) => {{
40        fn __check(targ: &$crate::Target) -> bool {
41            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - $vendor - $os - $env));
42
43            targ.vendor() == mtarg.vendor()
44                && targ.operating_system() == mtarg.operating_system()
45                && targ.environment() == mtarg.environment()
46                && targ.object_format() == mtarg.object_format()
47        }
48
49        __check
50    }};
51    (*-$vendor:ident-$sys:ident) => {{
52        fn __check(targ: &$crate::Target) -> bool {
53            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - $vendor - $sys));
54
55            targ.vendor() == mtarg.vendor()
56                && targ.operating_system() == mtarg.operating_system()
57                && targ.environment() == mtarg.environment()
58                && targ.object_format() == mtarg.object_format()
59        }
60
61        __check
62    }};
63
64    ($arch:ident-*-$os:ident-$env:ident) => {{
65        fn __check(targ: &$crate::Target) -> bool {
66            let mtarg = $crate::Target::parse($crate::__to_target!($arch - unknown - $os - $env));
67
68            targ.arch() == mtarg.arch()
69                && targ.operating_system() == mtarg.operating_system()
70                && targ.environment() == mtarg.environment()
71                && targ.object_format() == mtarg.object_format()
72        }
73
74        __check
75    }};
76    ($arch:ident-*-$sys:ident) => {{
77        fn __check(targ: &$crate::Target) -> bool {
78            let mtarg = $crate::Target::parse($crate::__to_target!($arch - unknown - $sys));
79
80            targ.arch() == mtarg.arch()
81                && targ.operating_system() == mtarg.operating_system()
82                && targ.environment() == mtarg.environment()
83                && targ.object_format() == mtarg.object_format()
84        }
85
86        __check
87    }};
88
89    ($arch:ident-$vendor:ident-*-$env:ident) => {{
90        fn __check(targ: &$crate::Target) -> bool {
91            let mtarg = $crate::Target::parse($crate::__to_target!($arch - $vendor - none - $env));
92
93            targ.arch() == mtarg.arch()
94                && targ.vendor() == mtarg.vendor()
95                && targ.environment() == mtarg.environment()
96                && targ.object_format() == mtarg.object_format()
97        }
98
99        __check
100    }};
101
102    ($arch:ident-$vendor:ident-*) => {{
103        fn __check(targ: &$crate::Target) -> bool {
104            let mtarg = $crate::Target::parse($crate::__to_target!($arch - $vendor - elf));
105
106            targ.arch() == mtarg.arch() && targ.vendor() == mtarg.vendor()
107        }
108
109        __check
110    }};
111
112    ($arch:ident-$vendor:ident-$os:ident-*) => {{
113        fn __check(targ: &$crate::Target) -> bool {
114            let mtarg = $crate::Target::parse($crate::__to_target!($arch - $vendor - $os - elf));
115
116            targ.vendor() == mtarg.vendor() && targ.operating_system() == mtarg.operating_system()
117        }
118
119        __check
120    }};
121
122    (*-*-$os:ident-$env:ident) => {{
123        fn __check(targ: &$crate::Target) -> bool {
124            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - unknown - $os - $env));
125
126            targ.operating_system() == mtarg.operating_system()
127                && targ.environment() == mtarg.environment()
128                && targ.object_format() == mtarg.object_format()
129        }
130
131        __check
132    }};
133    (*-*-$sys:ident) => {{
134        fn __check(targ: &$crate::Target) -> bool {
135            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - unknown - $sys));
136
137            targ.operating_system() == mtarg.operating_system()
138                && targ.environment() == mtarg.environment()
139                && targ.object_format() == mtarg.object_format()
140        }
141
142        __check
143    }};
144
145    (*-$vendor:ident-*-$env:ident) => {{
146        fn __check(targ: &$crate::Target) -> bool {
147            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - $vendor - none - $env));
148
149            targ.vendor() == mtarg.vendor()
150                && targ.environment() == mtarg.environment()
151                && targ.object_format() == mtarg.object_format()
152        }
153
154        __check
155    }};
156
157    (*-$vendor:ident-*) => {{
158        fn __check(targ: &$crate::Target) -> bool {
159            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - $vendor - elf));
160
161            targ.vendor() == mtarg.vendor()
162        }
163
164        __check
165    }};
166
167    (*-$vendor:ident-$os:ident-*) => {{
168        fn __check(targ: &$crate::Target) -> bool {
169            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - $vendor - $os - elf));
170
171            targ.vendor() == mtarg.vendor() && targ.operating_system() == mtarg.operating_system()
172        }
173
174        __check
175    }};
176
177    ($arch:ident-*-*-$env:ident) => {{
178        fn __check(targ: &$crate::Target) -> bool {
179            let mtarg = $crate::Target::parse($crate::__to_target!($arch - unknown - none - $env));
180
181            targ.arch() == mtarg.arch()
182                && targ.environment() == mtarg.environment()
183                && targ.object_format() == mtarg.object_format()
184        }
185
186        __check
187    }};
188
189    ($arch:ident-*-*) => {{
190        fn __check(targ: &$crate::Target) -> bool {
191            let mtarg = $crate::Target::parse($crate::__to_target!($arch - unknown - elf));
192
193            targ.arch() == mtarg.arch()
194        }
195
196        __check
197    }};
198
199    ($arch:ident-*-$os:ident-*) => {{
200        fn __check(targ: &$crate::Target) -> bool {
201            let mtarg = $crate::Target::parse($crate::__to_target!($arch - unknown - $os - elf));
202
203            targ.arch() == mtarg.arch() && targ.operating_system() == mtarg.operating_system()
204        }
205
206        __check
207    }};
208
209    (*-*-*-$env:ident) => {{
210        fn __check(targ: &$crate::Target) -> bool {
211            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - unknown - none - $env));
212
213            targ.environment() == mtarg.environment()
214                && targ.object_format() == mtarg.object_format()
215        }
216
217        __check
218    }};
219
220    (*-*-$os:ident-*) => {{
221        fn __check(targ: &$crate::Target) -> bool {
222            let mtarg = $crate::Target::parse($crate::__to_target!(x86_64 - unknown - $os - elf));
223
224            targ.operating_system() == mtarg.operating_system()
225        }
226
227        __check
228    }};
229
230    (*-*-*) => {{
231        fn __check(_: &$crate::Target) -> bool {
232            true
233        }
234        __check
235    }};
236
237    (*) => {{
238        fn __check(_: &$crate::Target) -> bool {
239            true
240        }
241        __check
242    }};
243}
244
245#[macro_export]
246macro_rules! match_targets{
247    {
248        match ($targ:expr) {
249            $($($comp:tt)-* => $exp:expr),* $(,)?
250        }
251    } => {
252        {
253            let __val: &$crate::Target = &$targ;
254            #[allow(unreachable_code)]
255            loop {
256                $(if ($crate::__match_target_pattern!($($comp)-*))(&__val){
257                    break $exp
258                })*
259
260                unreachable!("Incomplete Exhaustive Target Pattern (add a wildcard match as * => )")
261            }
262        }
263    }
264}
265
266#[cfg(test)]
267mod tests {
268    use crate::Target;
269
270    #[test]
271    pub fn test_match_easy() {
272        let target = Target::parse("x86_64-pc-linux-gnu");
273        match_targets! {
274            match (target) {
275                x86_64-pc-linux-gnu => {},
276                * => panic!("Invalid Target")
277            }
278        }
279    }
280
281    #[test]
282    pub fn test_match_ref() {
283        let target = Target::parse("x86_64-pc-linux-gnu");
284        match_targets! {
285            match (&target) {
286                x86_64-pc-linux-gnu => {},
287                * => panic!("Invalid Target")
288            }
289        }
290    }
291
292    #[test]
293    pub fn target_match_arch_wildcard() {
294        let target = Target::parse("x86_64-pc-linux-gnu");
295        match_targets! {
296            match (target) {
297                *-pc-linux-gnu => {},
298                * => panic!("Invalid Target")
299            }
300        }
301    }
302
303    #[test]
304    pub fn target_match_vendor_wildcard() {
305        let target = Target::parse("x86_64-pc-linux-gnu");
306        match_targets! {
307            match (target) {
308                x86_64-*-linux-gnu => {},
309                * => panic!("Invalid Target")
310            }
311        }
312    }
313
314    #[test]
315    pub fn target_match_os_wildcard() {
316        let target = Target::parse("x86_64-pc-linux-gnu");
317        match_targets! {
318            match (target) {
319                x86_64-pc-*-gnu => {},
320                * => panic!("Invalid Target")
321            }
322        }
323    }
324
325    #[test]
326    pub fn target_match_env_wildcard() {
327        let target = Target::parse("x86_64-pc-linux-gnu");
328        match_targets! {
329            match (target) {
330                x86_64-pc-linux-* => {},
331                * => panic!("Invalid Target")
332            }
333        }
334    }
335
336    #[test]
337    pub fn target_match_sys_wildcard() {
338        let target = Target::parse("x86_64-pc-linux-gnu");
339        match_targets! {
340            match (target) {
341                x86_64-pc-* => {},
342                * => panic!("Invalid Target")
343            }
344        }
345    }
346
347    #[test]
348    pub fn target_match_first() {
349        let target = Target::parse("x86_64-pc-linux-gnu");
350        match_targets! {
351            match (target) {
352                x86_64-pc-linux-gnu => {},
353                x86_64-*-linux-* => panic!("Incorrect Match"),
354                * => panic!("Incorrect Match"),
355            }
356        }
357    }
358
359    #[test]
360    pub fn target_match_ignore_wrong_matches() {
361        let target = Target::parse("x86_64-pc-linux-gnu");
362        match_targets! {
363            match (target){
364                i686-*-linux-gnu => panic!("Incorrect Match"),
365                x86_64-*-linux-gnu => {},
366                * => panic!("Incorrect Match")
367            }
368        }
369    }
370}