1use crate::triple::{Endianness, PointerWidth, Triple};
4use alloc::borrow::Cow;
5use alloc::boxed::Box;
6use alloc::format;
7use alloc::string::String;
8use core::fmt;
9use core::hash::{Hash, Hasher};
10use core::str::FromStr;
11
12#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
15#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
16#[allow(missing_docs)]
17pub enum Architecture {
18 Unknown,
19 Arm(ArmArchitecture),
20 AmdGcn,
21 Aarch64(Aarch64Architecture),
22 Asmjs,
23 Avr,
24 Bpfeb,
25 Bpfel,
26 Hexagon,
27 X86_32(X86_32Architecture),
28 M68k,
29 LoongArch64,
30 Mips32(Mips32Architecture),
31 Mips64(Mips64Architecture),
32 Msp430,
33 Nvptx64,
34 Pulley32,
35 Pulley64,
36 Pulley32be,
37 Pulley64be,
38 Powerpc,
39 Powerpc64,
40 Powerpc64le,
41 Riscv32(Riscv32Architecture),
42 Riscv64(Riscv64Architecture),
43 S390x,
44 Sparc,
45 Sparc64,
46 Sparcv9,
47 Wasm32,
48 Wasm64,
49 X86_64,
50 X86_64h,
52 XTensa,
53 Clever(CleverArchitecture),
54 #[cfg(feature = "arch_zkasm")]
58 ZkAsm,
59}
60
61#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
62#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
63#[allow(missing_docs)]
64pub enum ArmArchitecture {
65 Arm, Armeb,
67 Armv4,
68 Armv4t,
69 Armv5t,
70 Armv5te,
71 Armv5tej,
72 Armv6,
73 Armv6j,
74 Armv6k,
75 Armv6z,
76 Armv6kz,
77 Armv6t2,
78 Armv6m,
79 Armv7,
80 Armv7a,
81 Armv7k,
82 Armv7ve,
83 Armv7m,
84 Armv7r,
85 Armv7s,
86 Armv8,
87 Armv8a,
88 Armv8_1a,
89 Armv8_2a,
90 Armv8_3a,
91 Armv8_4a,
92 Armv8_5a,
93 Armv8mBase,
94 Armv8mMain,
95 Armv8r,
96
97 Armebv7r,
98
99 Thumbeb,
100 Thumbv4t,
101 Thumbv5te,
102 Thumbv6m,
103 Thumbv7a,
104 Thumbv7em,
105 Thumbv7m,
106 Thumbv7neon,
107 Thumbv8mBase,
108 Thumbv8mMain,
109}
110
111#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
112#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
113#[allow(missing_docs)]
114pub enum Aarch64Architecture {
115 Aarch64,
116 Aarch64be,
117}
118
119impl ArmArchitecture {
143 #[rustfmt::skip]
145 pub fn is_thumb(self) -> bool {
146 use ArmArchitecture::*;
147
148 match self {
149 Arm
150 | Armeb
151 | Armv4
152 | Armv4t
153 | Armv5t
154 | Armv5te
155 | Armv5tej
156 | Armv6
157 | Armv6j
158 | Armv6k
159 | Armv6z
160 | Armv6kz
161 | Armv6t2
162 | Armv6m
163 | Armv7
164 | Armv7a
165 | Armv7k
166 | Armv7ve
167 | Armv7m
168 | Armv7r
169 | Armv7s
170 | Armv8
171 | Armv8a
172 | Armv8_1a
173 | Armv8_2a
174 | Armv8_3a
175 | Armv8_4a
176 | Armv8_5a
177 | Armv8mBase
178 | Armv8mMain
179 | Armv8r
180 | Armebv7r => false,
181 Thumbeb
182 | Thumbv4t
183 | Thumbv5te
184 | Thumbv6m
185 | Thumbv7a
186 | Thumbv7em
187 | Thumbv7m
188 | Thumbv7neon
189 | Thumbv8mBase
190 | Thumbv8mMain => true,
191 }
192 }
193
194 #[rustfmt::skip]
200 pub fn pointer_width(self) -> PointerWidth {
201 use ArmArchitecture::*;
202
203 match self {
204 Arm
205 | Armeb
206 | Armv4
207 | Armv4t
208 | Armv5t
209 | Armv5te
210 | Armv5tej
211 | Armv6
212 | Armv6j
213 | Armv6k
214 | Armv6z
215 | Armv6kz
216 | Armv6t2
217 | Armv6m
218 | Armv7
219 | Armv7a
220 | Armv7k
221 | Armv7ve
222 | Armv7m
223 | Armv7r
224 | Armv7s
225 | Armv8
226 | Armv8a
227 | Armv8_1a
228 | Armv8_2a
229 | Armv8_3a
230 | Armv8_4a
231 | Armv8_5a
232 | Armv8mBase
233 | Armv8mMain
234 | Armv8r
235 | Armebv7r
236 | Thumbeb
237 | Thumbv4t
238 | Thumbv5te
239 | Thumbv6m
240 | Thumbv7a
241 | Thumbv7em
242 | Thumbv7m
243 | Thumbv7neon
244 | Thumbv8mBase
245 | Thumbv8mMain => PointerWidth::U32,
246 }
247 }
248
249 #[rustfmt::skip]
251 pub fn endianness(self) -> Endianness {
252 use ArmArchitecture::*;
253
254 match self {
255 Arm
256 | Armv4
257 | Armv4t
258 | Armv5t
259 | Armv5te
260 | Armv5tej
261 | Armv6
262 | Armv6j
263 | Armv6k
264 | Armv6z
265 | Armv6kz
266 | Armv6t2
267 | Armv6m
268 | Armv7
269 | Armv7a
270 | Armv7k
271 | Armv7ve
272 | Armv7m
273 | Armv7r
274 | Armv7s
275 | Armv8
276 | Armv8a
277 | Armv8_1a
278 | Armv8_2a
279 | Armv8_3a
280 | Armv8_4a
281 | Armv8_5a
282 | Armv8mBase
283 | Armv8mMain
284 | Armv8r
285 | Thumbv4t
286 | Thumbv5te
287 | Thumbv6m
288 | Thumbv7a
289 | Thumbv7em
290 | Thumbv7m
291 | Thumbv7neon
292 | Thumbv8mBase
293 | Thumbv8mMain => Endianness::Little,
294 Armeb | Armebv7r | Thumbeb => Endianness::Big,
295 }
296 }
297
298 pub fn into_str(self) -> Cow<'static, str> {
300 use ArmArchitecture::*;
301
302 match self {
303 Arm => Cow::Borrowed("arm"),
304 Armeb => Cow::Borrowed("armeb"),
305 Armv4 => Cow::Borrowed("armv4"),
306 Armv4t => Cow::Borrowed("armv4t"),
307 Armv5t => Cow::Borrowed("armv5t"),
308 Armv5te => Cow::Borrowed("armv5te"),
309 Armv5tej => Cow::Borrowed("armv5tej"),
310 Armv6 => Cow::Borrowed("armv6"),
311 Armv6j => Cow::Borrowed("armv6j"),
312 Armv6k => Cow::Borrowed("armv6k"),
313 Armv6z => Cow::Borrowed("armv6z"),
314 Armv6kz => Cow::Borrowed("armv6kz"),
315 Armv6t2 => Cow::Borrowed("armv6t2"),
316 Armv6m => Cow::Borrowed("armv6m"),
317 Armv7 => Cow::Borrowed("armv7"),
318 Armv7a => Cow::Borrowed("armv7a"),
319 Armv7k => Cow::Borrowed("armv7k"),
320 Armv7ve => Cow::Borrowed("armv7ve"),
321 Armv7m => Cow::Borrowed("armv7m"),
322 Armv7r => Cow::Borrowed("armv7r"),
323 Armv7s => Cow::Borrowed("armv7s"),
324 Armv8 => Cow::Borrowed("armv8"),
325 Armv8a => Cow::Borrowed("armv8a"),
326 Armv8_1a => Cow::Borrowed("armv8.1a"),
327 Armv8_2a => Cow::Borrowed("armv8.2a"),
328 Armv8_3a => Cow::Borrowed("armv8.3a"),
329 Armv8_4a => Cow::Borrowed("armv8.4a"),
330 Armv8_5a => Cow::Borrowed("armv8.5a"),
331 Armv8mBase => Cow::Borrowed("armv8m.base"),
332 Armv8mMain => Cow::Borrowed("armv8m.main"),
333 Armv8r => Cow::Borrowed("armv8r"),
334 Thumbeb => Cow::Borrowed("thumbeb"),
335 Thumbv4t => Cow::Borrowed("thumbv4t"),
336 Thumbv5te => Cow::Borrowed("thumbv5te"),
337 Thumbv6m => Cow::Borrowed("thumbv6m"),
338 Thumbv7a => Cow::Borrowed("thumbv7a"),
339 Thumbv7em => Cow::Borrowed("thumbv7em"),
340 Thumbv7m => Cow::Borrowed("thumbv7m"),
341 Thumbv7neon => Cow::Borrowed("thumbv7neon"),
342 Thumbv8mBase => Cow::Borrowed("thumbv8m.base"),
343 Thumbv8mMain => Cow::Borrowed("thumbv8m.main"),
344 Armebv7r => Cow::Borrowed("armebv7r"),
345 }
346 }
347}
348
349impl Aarch64Architecture {
350 pub fn is_thumb(self) -> bool {
352 match self {
353 Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false,
354 }
355 }
356
357 pub fn pointer_width(self) -> PointerWidth {
366 match self {
367 Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64,
368 }
369 }
370
371 pub fn endianness(self) -> Endianness {
373 match self {
374 Aarch64Architecture::Aarch64 => Endianness::Little,
375 Aarch64Architecture::Aarch64be => Endianness::Big,
376 }
377 }
378
379 pub fn into_str(self) -> Cow<'static, str> {
381 use Aarch64Architecture::*;
382
383 match self {
384 Aarch64 => Cow::Borrowed("aarch64"),
385 Aarch64be => Cow::Borrowed("aarch64_be"),
386 }
387 }
388}
389
390#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
391#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
392#[allow(missing_docs)]
393pub enum CleverArchitecture {
394 Clever,
395 Clever1_0,
396}
397
398impl CleverArchitecture {
399 pub fn into_str(self) -> Cow<'static, str> {
401 use CleverArchitecture::*;
402
403 match self {
404 Clever => Cow::Borrowed("clever"),
405 Clever1_0 => Cow::Borrowed("clever1.0"),
406 }
407 }
408}
409
410#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
412#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
413#[allow(missing_docs)]
414pub enum Riscv32Architecture {
415 Riscv32,
416 Riscv32gc,
417 Riscv32i,
418 Riscv32im,
419 Riscv32ima,
420 Riscv32imac,
421 Riscv32imafc,
422 Riscv32imc,
423}
424
425impl Riscv32Architecture {
426 pub fn into_str(self) -> Cow<'static, str> {
428 use Riscv32Architecture::*;
429
430 match self {
431 Riscv32 => Cow::Borrowed("riscv32"),
432 Riscv32gc => Cow::Borrowed("riscv32gc"),
433 Riscv32i => Cow::Borrowed("riscv32i"),
434 Riscv32im => Cow::Borrowed("riscv32im"),
435 Riscv32ima => Cow::Borrowed("riscv32ima"),
436 Riscv32imac => Cow::Borrowed("riscv32imac"),
437 Riscv32imafc => Cow::Borrowed("riscv32imafc"),
438 Riscv32imc => Cow::Borrowed("riscv32imc"),
439 }
440 }
441}
442
443#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
445#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
446#[allow(missing_docs)]
447pub enum Riscv64Architecture {
448 Riscv64,
449 Riscv64gc,
450 Riscv64imac,
451}
452
453impl Riscv64Architecture {
454 pub fn into_str(self) -> Cow<'static, str> {
456 use Riscv64Architecture::*;
457
458 match self {
459 Riscv64 => Cow::Borrowed("riscv64"),
460 Riscv64gc => Cow::Borrowed("riscv64gc"),
461 Riscv64imac => Cow::Borrowed("riscv64imac"),
462 }
463 }
464}
465
466#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
468#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
469#[allow(missing_docs)]
470pub enum X86_32Architecture {
471 I386,
472 I586,
473 I686,
474}
475
476impl X86_32Architecture {
477 pub fn into_str(self) -> Cow<'static, str> {
479 use X86_32Architecture::*;
480
481 match self {
482 I386 => Cow::Borrowed("i386"),
483 I586 => Cow::Borrowed("i586"),
484 I686 => Cow::Borrowed("i686"),
485 }
486 }
487}
488
489#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
491#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
492#[allow(missing_docs)]
493pub enum Mips32Architecture {
494 Mips,
495 Mipsel,
496 Mipsisa32r6,
497 Mipsisa32r6el,
498}
499
500impl Mips32Architecture {
501 pub fn into_str(self) -> Cow<'static, str> {
503 use Mips32Architecture::*;
504
505 match self {
506 Mips => Cow::Borrowed("mips"),
507 Mipsel => Cow::Borrowed("mipsel"),
508 Mipsisa32r6 => Cow::Borrowed("mipsisa32r6"),
509 Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el"),
510 }
511 }
512}
513
514#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
516#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
517#[allow(missing_docs)]
518pub enum Mips64Architecture {
519 Mips64,
520 Mips64el,
521 Mipsisa64r6,
522 Mipsisa64r6el,
523}
524
525impl Mips64Architecture {
526 pub fn into_str(self) -> Cow<'static, str> {
528 use Mips64Architecture::*;
529
530 match self {
531 Mips64 => Cow::Borrowed("mips64"),
532 Mips64el => Cow::Borrowed("mips64el"),
533 Mipsisa64r6 => Cow::Borrowed("mipsisa64r6"),
534 Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el"),
535 }
536 }
537}
538
539#[derive(Clone, Debug, Eq)]
542pub enum CustomVendor {
543 Owned(Box<String>),
545 Static(&'static str),
548}
549
550impl CustomVendor {
551 pub fn as_str(&self) -> &str {
553 match self {
554 CustomVendor::Owned(s) => s,
555 CustomVendor::Static(s) => s,
556 }
557 }
558}
559
560impl PartialEq for CustomVendor {
561 fn eq(&self, other: &Self) -> bool {
562 self.as_str() == other.as_str()
563 }
564}
565
566impl Hash for CustomVendor {
567 fn hash<H: Hasher>(&self, state: &mut H) {
568 self.as_str().hash(state)
569 }
570}
571
572#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
575#[derive(Clone, Debug, PartialEq, Eq, Hash)]
576#[allow(missing_docs)]
577pub enum Vendor {
578 Unknown,
579 Amd,
580 Apple,
581 Espressif,
582 Experimental,
583 Fortanix,
584 Ibm,
585 Kmc,
586 Nintendo,
587 Nvidia,
588 Pc,
589 Rumprun,
590 Sun,
591 Uwp,
592 Wrs,
593
594 Custom(CustomVendor),
602}
603
604impl Vendor {
605 pub fn as_str(&self) -> &str {
607 use Vendor::*;
608
609 match self {
610 Unknown => "unknown",
611 Amd => "amd",
612 Apple => "apple",
613 Espressif => "espressif",
614 Experimental => "experimental",
615 Fortanix => "fortanix",
616 Ibm => "ibm",
617 Kmc => "kmc",
618 Nintendo => "nintendo",
619 Nvidia => "nvidia",
620 Pc => "pc",
621 Rumprun => "rumprun",
622 Sun => "sun",
623 Uwp => "uwp",
624 Wrs => "wrs",
625 Custom(name) => name.as_str(),
626 }
627 }
628}
629
630#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
636#[allow(missing_docs)]
637pub struct DeploymentTarget {
638 pub major: u16,
639 pub minor: u8,
640 pub patch: u8,
641}
642
643#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
650#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
651#[allow(missing_docs)]
652pub enum OperatingSystem {
653 Unknown,
654 Aix,
655 AmdHsa,
656 Bitrig,
657 Cloudabi,
658 Cuda,
659 Darwin(Option<DeploymentTarget>),
670 Dragonfly,
671 Emscripten,
672 Espidf,
673 Freebsd,
674 Fuchsia,
675 Haiku,
676 Hermit,
677 Horizon,
678 Hurd,
679 Illumos,
680 IOS(Option<DeploymentTarget>),
681 L4re,
682 Linux,
683 MacOSX(Option<DeploymentTarget>),
688 Nebulet,
689 Netbsd,
690 None_,
691 Openbsd,
692 Psp,
693 Redox,
694 Solaris,
695 SolidAsp3,
696 TvOS(Option<DeploymentTarget>),
697 Uefi,
698 VisionOS(Option<DeploymentTarget>),
699 VxWorks,
700 Wasi,
701 WasiP1,
702 WasiP2,
703 WatchOS(Option<DeploymentTarget>),
704 Windows,
705 XROS(Option<DeploymentTarget>),
707}
708
709impl OperatingSystem {
710 pub fn into_str(self) -> Cow<'static, str> {
712 use OperatingSystem::*;
713
714 let darwin_version = |name, deployment_target| {
715 if let Some(DeploymentTarget {
716 major,
717 minor,
718 patch,
719 }) = deployment_target
720 {
721 Cow::Owned(format!("{}{}.{}.{}", name, major, minor, patch))
722 } else {
723 Cow::Borrowed(name)
724 }
725 };
726
727 match self {
728 Unknown => Cow::Borrowed("unknown"),
729 Aix => Cow::Borrowed("aix"),
730 AmdHsa => Cow::Borrowed("amdhsa"),
731 Bitrig => Cow::Borrowed("bitrig"),
732 Cloudabi => Cow::Borrowed("cloudabi"),
733 Cuda => Cow::Borrowed("cuda"),
734 Darwin(deployment_target) => darwin_version("darwin", deployment_target),
735 Dragonfly => Cow::Borrowed("dragonfly"),
736 Emscripten => Cow::Borrowed("emscripten"),
737 Espidf => Cow::Borrowed("espidf"),
738 Freebsd => Cow::Borrowed("freebsd"),
739 Fuchsia => Cow::Borrowed("fuchsia"),
740 Haiku => Cow::Borrowed("haiku"),
741 Hermit => Cow::Borrowed("hermit"),
742 Horizon => Cow::Borrowed("horizon"),
743 Hurd => Cow::Borrowed("hurd"),
744 Illumos => Cow::Borrowed("illumos"),
745 IOS(deployment_target) => darwin_version("ios", deployment_target),
746 L4re => Cow::Borrowed("l4re"),
747 Linux => Cow::Borrowed("linux"),
748 MacOSX(deployment_target) => darwin_version("macosx", deployment_target),
749 Nebulet => Cow::Borrowed("nebulet"),
750 Netbsd => Cow::Borrowed("netbsd"),
751 None_ => Cow::Borrowed("none"),
752 Openbsd => Cow::Borrowed("openbsd"),
753 Psp => Cow::Borrowed("psp"),
754 Redox => Cow::Borrowed("redox"),
755 Solaris => Cow::Borrowed("solaris"),
756 SolidAsp3 => Cow::Borrowed("solid_asp3"),
757 TvOS(deployment_target) => darwin_version("tvos", deployment_target),
758 Uefi => Cow::Borrowed("uefi"),
759 VxWorks => Cow::Borrowed("vxworks"),
760 VisionOS(deployment_target) => darwin_version("visionos", deployment_target),
761 Wasi => Cow::Borrowed("wasi"),
762 WasiP1 => Cow::Borrowed("wasip1"),
763 WasiP2 => Cow::Borrowed("wasip2"),
764 WatchOS(deployment_target) => darwin_version("watchos", deployment_target),
765 Windows => Cow::Borrowed("windows"),
766 XROS(deployment_target) => darwin_version("xros", deployment_target),
767 }
768 }
769
770 pub fn is_like_darwin(&self) -> bool {
781 use OperatingSystem::*;
782
783 match self {
784 Darwin(_) | IOS(_) | MacOSX(_) | TvOS(_) | VisionOS(_) | WatchOS(_) | XROS(_) => true,
785 _ => false,
786 }
787 }
788}
789
790#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
794#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
795#[allow(missing_docs)]
796pub enum Environment {
797 Unknown,
798 AmdGiz,
799 Android,
800 Androideabi,
801 Eabi,
802 Eabihf,
803 Gnu,
804 Gnuabi64,
805 Gnueabi,
806 Gnueabihf,
807 Gnuspe,
808 Gnux32,
809 GnuIlp32,
810 GnuLlvm,
811 HermitKernel,
812 HurdKernel,
813 LinuxKernel,
814 Macabi,
815 Musl,
816 Musleabi,
817 Musleabihf,
818 Muslabi64,
819 Msvc,
820 Newlib,
821 None,
822 Kernel,
823 Uclibc,
824 Uclibceabi,
825 Uclibceabihf,
826 Sgx,
827 Sim,
828 Softfloat,
829 Spe,
830 Threads,
831 Ohos,
832}
833
834impl Environment {
835 pub fn into_str(self) -> Cow<'static, str> {
837 use Environment::*;
838
839 match self {
840 Unknown => Cow::Borrowed("unknown"),
841 AmdGiz => Cow::Borrowed("amdgiz"),
842 Android => Cow::Borrowed("android"),
843 Androideabi => Cow::Borrowed("androideabi"),
844 Eabi => Cow::Borrowed("eabi"),
845 Eabihf => Cow::Borrowed("eabihf"),
846 Gnu => Cow::Borrowed("gnu"),
847 Gnuabi64 => Cow::Borrowed("gnuabi64"),
848 Gnueabi => Cow::Borrowed("gnueabi"),
849 Gnueabihf => Cow::Borrowed("gnueabihf"),
850 Gnuspe => Cow::Borrowed("gnuspe"),
851 Gnux32 => Cow::Borrowed("gnux32"),
852 GnuIlp32 => Cow::Borrowed("gnu_ilp32"),
853 GnuLlvm => Cow::Borrowed("gnullvm"),
854 HermitKernel => Cow::Borrowed("hermitkernel"),
855 HurdKernel => Cow::Borrowed("hurdkernel"),
856 LinuxKernel => Cow::Borrowed("linuxkernel"),
857 Macabi => Cow::Borrowed("macabi"),
858 Musl => Cow::Borrowed("musl"),
859 Musleabi => Cow::Borrowed("musleabi"),
860 Musleabihf => Cow::Borrowed("musleabihf"),
861 Muslabi64 => Cow::Borrowed("muslabi64"),
862 Msvc => Cow::Borrowed("msvc"),
863 Newlib => Cow::Borrowed("newlib"),
864 None => Cow::Borrowed("none"),
865 Kernel => Cow::Borrowed("kernel"),
866 Uclibc => Cow::Borrowed("uclibc"),
867 Uclibceabi => Cow::Borrowed("uclibceabi"),
868 Uclibceabihf => Cow::Borrowed("uclibceabihf"),
869 Sgx => Cow::Borrowed("sgx"),
870 Sim => Cow::Borrowed("sim"),
871 Softfloat => Cow::Borrowed("softfloat"),
872 Spe => Cow::Borrowed("spe"),
873 Threads => Cow::Borrowed("threads"),
874 Ohos => Cow::Borrowed("ohos"),
875 }
876 }
877}
878
879#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
882#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
883#[allow(missing_docs)]
884pub enum BinaryFormat {
885 Unknown,
886 Elf,
887 Coff,
888 Macho,
889 Wasm,
890 Xcoff,
891}
892
893impl BinaryFormat {
894 pub fn into_str(self) -> Cow<'static, str> {
896 use BinaryFormat::*;
897
898 match self {
899 Unknown => Cow::Borrowed("unknown"),
900 Elf => Cow::Borrowed("elf"),
901 Coff => Cow::Borrowed("coff"),
902 Macho => Cow::Borrowed("macho"),
903 Wasm => Cow::Borrowed("wasm"),
904 Xcoff => Cow::Borrowed("xcoff"),
905 }
906 }
907}
908
909impl Architecture {
910 #[rustfmt::skip]
912 pub fn endianness(self) -> Result<Endianness, ()> {
913 use Architecture::*;
914
915 match self {
916 Unknown => Err(()),
917 Arm(arm) => Ok(arm.endianness()),
918 Aarch64(aarch) => Ok(aarch.endianness()),
919 AmdGcn
920 | Asmjs
921 | Avr
922 | Bpfel
923 | Hexagon
924 | X86_32(_)
925 | LoongArch64
926 | Mips64(Mips64Architecture::Mips64el)
927 | Mips32(Mips32Architecture::Mipsel)
928 | Mips32(Mips32Architecture::Mipsisa32r6el)
929 | Mips64(Mips64Architecture::Mipsisa64r6el)
930 | Msp430
931 | Nvptx64
932 | Pulley32
933 | Pulley64
934 | Powerpc64le
935 | Riscv32(_)
936 | Riscv64(_)
937 | Wasm32
938 | Wasm64
939 | X86_64
940 | X86_64h
941 | XTensa
942 | Clever(_) => Ok(Endianness::Little),
943 Bpfeb
944 | M68k
945 | Mips32(Mips32Architecture::Mips)
946 | Mips64(Mips64Architecture::Mips64)
947 | Mips32(Mips32Architecture::Mipsisa32r6)
948 | Mips64(Mips64Architecture::Mipsisa64r6)
949 | Powerpc
950 | Powerpc64
951 | Pulley32be
952 | Pulley64be
953 | S390x
954 | Sparc
955 | Sparc64
956 | Sparcv9 => Ok(Endianness::Big),
957 #[cfg(feature="arch_zkasm")]
958 ZkAsm => Ok(Endianness::Big),
959 }
960 }
961
962 #[rustfmt::skip]
967 pub fn pointer_width(self) -> Result<PointerWidth, ()> {
968 use Architecture::*;
969
970 match self {
971 Unknown => Err(()),
972 Avr | Msp430 => Ok(PointerWidth::U16),
973 Arm(arm) => Ok(arm.pointer_width()),
974 Aarch64(aarch) => Ok(aarch.pointer_width()),
975 Asmjs
976 | Hexagon
977 | X86_32(_)
978 | Riscv32(_)
979 | Sparc
980 | Wasm32
981 | M68k
982 | Mips32(_)
983 | Pulley32
984 | Pulley32be
985 | Powerpc
986 | XTensa => Ok(PointerWidth::U32),
987 AmdGcn
988 | Bpfeb
989 | Bpfel
990 | Powerpc64le
991 | Riscv64(_)
992 | X86_64
993 | X86_64h
994 | Mips64(_)
995 | Nvptx64
996 | Pulley64
997 | Pulley64be
998 | Powerpc64
999 | S390x
1000 | Sparc64
1001 | Sparcv9
1002 | LoongArch64
1003 | Wasm64
1004 | Clever(_) => Ok(PointerWidth::U64),
1005 #[cfg(feature="arch_zkasm")]
1006 ZkAsm => Ok(PointerWidth::U64),
1007 }
1008 }
1009
1010 pub fn is_clever(&self) -> bool {
1012 match self {
1013 Architecture::Clever(_) => true,
1014 _ => false,
1015 }
1016 }
1017
1018 pub fn into_str(self) -> Cow<'static, str> {
1020 use Architecture::*;
1021
1022 match self {
1023 Arm(arm) => arm.into_str(),
1024 Aarch64(aarch) => aarch.into_str(),
1025 Unknown => Cow::Borrowed("unknown"),
1026 AmdGcn => Cow::Borrowed("amdgcn"),
1027 Asmjs => Cow::Borrowed("asmjs"),
1028 Avr => Cow::Borrowed("avr"),
1029 Bpfeb => Cow::Borrowed("bpfeb"),
1030 Bpfel => Cow::Borrowed("bpfel"),
1031 Hexagon => Cow::Borrowed("hexagon"),
1032 X86_32(x86_32) => x86_32.into_str(),
1033 LoongArch64 => Cow::Borrowed("loongarch64"),
1034 M68k => Cow::Borrowed("m68k"),
1035 Mips32(mips32) => mips32.into_str(),
1036 Mips64(mips64) => mips64.into_str(),
1037 Msp430 => Cow::Borrowed("msp430"),
1038 Nvptx64 => Cow::Borrowed("nvptx64"),
1039 Pulley32 => Cow::Borrowed("pulley32"),
1040 Pulley64 => Cow::Borrowed("pulley64"),
1041 Pulley32be => Cow::Borrowed("pulley32be"),
1042 Pulley64be => Cow::Borrowed("pulley64be"),
1043 Powerpc => Cow::Borrowed("powerpc"),
1044 Powerpc64 => Cow::Borrowed("powerpc64"),
1045 Powerpc64le => Cow::Borrowed("powerpc64le"),
1046 Riscv32(riscv32) => riscv32.into_str(),
1047 Riscv64(riscv64) => riscv64.into_str(),
1048 S390x => Cow::Borrowed("s390x"),
1049 Sparc => Cow::Borrowed("sparc"),
1050 Sparc64 => Cow::Borrowed("sparc64"),
1051 Sparcv9 => Cow::Borrowed("sparcv9"),
1052 Wasm32 => Cow::Borrowed("wasm32"),
1053 Wasm64 => Cow::Borrowed("wasm64"),
1054 X86_64 => Cow::Borrowed("x86_64"),
1055 X86_64h => Cow::Borrowed("x86_64h"),
1056 XTensa => Cow::Borrowed("xtensa"),
1057 Clever(ver) => ver.into_str(),
1058 #[cfg(feature = "arch_zkasm")]
1059 ZkAsm => Cow::Borrowed("zkasm"),
1060 }
1061 }
1062}
1063
1064pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat {
1067 match triple.operating_system {
1068 OperatingSystem::None_ => match triple.environment {
1069 Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf,
1070 _ => BinaryFormat::Unknown,
1071 },
1072 OperatingSystem::Aix => BinaryFormat::Xcoff,
1073 os if os.is_like_darwin() => BinaryFormat::Macho,
1074 OperatingSystem::Windows => BinaryFormat::Coff,
1075 OperatingSystem::Nebulet
1076 | OperatingSystem::Emscripten
1077 | OperatingSystem::VxWorks
1078 | OperatingSystem::Wasi
1079 | OperatingSystem::Unknown => match triple.architecture {
1080 Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm,
1081 Architecture::Unknown => BinaryFormat::Unknown,
1082 _ => BinaryFormat::Elf,
1084 },
1085 _ => BinaryFormat::Elf,
1086 }
1087}
1088
1089impl fmt::Display for ArmArchitecture {
1090 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1091 f.write_str(&self.into_str())
1092 }
1093}
1094
1095impl fmt::Display for Aarch64Architecture {
1096 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1097 f.write_str(&self.into_str())
1098 }
1099}
1100
1101impl fmt::Display for CleverArchitecture {
1102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1103 f.write_str(&self.into_str())
1104 }
1105}
1106
1107impl fmt::Display for Riscv32Architecture {
1108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1109 f.write_str(&self.into_str())
1110 }
1111}
1112
1113impl fmt::Display for Riscv64Architecture {
1114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1115 f.write_str(&self.into_str())
1116 }
1117}
1118
1119impl fmt::Display for X86_32Architecture {
1120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1121 f.write_str(&self.into_str())
1122 }
1123}
1124
1125impl fmt::Display for Mips32Architecture {
1126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1127 f.write_str(&self.into_str())
1128 }
1129}
1130
1131impl fmt::Display for Mips64Architecture {
1132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1133 f.write_str(&self.into_str())
1134 }
1135}
1136
1137impl fmt::Display for Architecture {
1138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1139 f.write_str(&self.into_str())
1140 }
1141}
1142
1143impl FromStr for ArmArchitecture {
1144 type Err = ();
1145
1146 fn from_str(s: &str) -> Result<Self, ()> {
1147 use ArmArchitecture::*;
1148
1149 Ok(match s {
1150 "arm" => Arm,
1151 "armeb" => Armeb,
1152 "armv4" => Armv4,
1153 "armv4t" => Armv4t,
1154 "armv5t" => Armv5t,
1155 "armv5te" => Armv5te,
1156 "armv5tej" => Armv5tej,
1157 "armv6" => Armv6,
1158 "armv6j" => Armv6j,
1159 "armv6k" => Armv6k,
1160 "armv6z" => Armv6z,
1161 "armv6kz" => Armv6kz,
1162 "armv6t2" => Armv6t2,
1163 "armv6m" => Armv6m,
1164 "armv7" => Armv7,
1165 "armv7a" => Armv7a,
1166 "armv7k" => Armv7k,
1167 "armv7ve" => Armv7ve,
1168 "armv7m" => Armv7m,
1169 "armv7r" => Armv7r,
1170 "armv7s" => Armv7s,
1171 "armv8" => Armv8,
1172 "armv8a" => Armv8a,
1173 "armv8.1a" => Armv8_1a,
1174 "armv8.2a" => Armv8_2a,
1175 "armv8.3a" => Armv8_3a,
1176 "armv8.4a" => Armv8_4a,
1177 "armv8.5a" => Armv8_5a,
1178 "armv8m.base" => Armv8mBase,
1179 "armv8m.main" => Armv8mMain,
1180 "armv8r" => Armv8r,
1181 "thumbeb" => Thumbeb,
1182 "thumbv4t" => Thumbv4t,
1183 "thumbv5te" => Thumbv5te,
1184 "thumbv6m" => Thumbv6m,
1185 "thumbv7a" => Thumbv7a,
1186 "thumbv7em" => Thumbv7em,
1187 "thumbv7m" => Thumbv7m,
1188 "thumbv7neon" => Thumbv7neon,
1189 "thumbv8m.base" => Thumbv8mBase,
1190 "thumbv8m.main" => Thumbv8mMain,
1191 "armebv7r" => Armebv7r,
1192 _ => return Err(()),
1193 })
1194 }
1195}
1196
1197impl FromStr for Aarch64Architecture {
1198 type Err = ();
1199
1200 fn from_str(s: &str) -> Result<Self, ()> {
1201 use Aarch64Architecture::*;
1202
1203 Ok(match s {
1204 "aarch64" => Aarch64,
1205 "arm64" => Aarch64,
1206 "aarch64_be" => Aarch64be,
1207 _ => return Err(()),
1208 })
1209 }
1210}
1211
1212impl FromStr for CleverArchitecture {
1213 type Err = ();
1214 fn from_str(s: &str) -> Result<Self, ()> {
1215 match s {
1216 "clever" => Ok(CleverArchitecture::Clever),
1217 "clever1.0" => Ok(CleverArchitecture::Clever1_0),
1218 _ => Err(()),
1219 }
1220 }
1221}
1222
1223impl FromStr for Riscv32Architecture {
1224 type Err = ();
1225
1226 fn from_str(s: &str) -> Result<Self, ()> {
1227 use Riscv32Architecture::*;
1228
1229 Ok(match s {
1230 "riscv32" => Riscv32,
1231 "riscv32gc" => Riscv32gc,
1232 "riscv32i" => Riscv32i,
1233 "riscv32im" => Riscv32im,
1234 "riscv32ima" => Riscv32ima,
1235 "riscv32imac" => Riscv32imac,
1236 "riscv32imafc" => Riscv32imafc,
1237 "riscv32imc" => Riscv32imc,
1238 _ => return Err(()),
1239 })
1240 }
1241}
1242
1243impl FromStr for Riscv64Architecture {
1244 type Err = ();
1245
1246 fn from_str(s: &str) -> Result<Self, ()> {
1247 use Riscv64Architecture::*;
1248
1249 Ok(match s {
1250 "riscv64" => Riscv64,
1251 "riscv64gc" => Riscv64gc,
1252 "riscv64imac" => Riscv64imac,
1253 _ => return Err(()),
1254 })
1255 }
1256}
1257
1258impl FromStr for X86_32Architecture {
1259 type Err = ();
1260
1261 fn from_str(s: &str) -> Result<Self, ()> {
1262 use X86_32Architecture::*;
1263
1264 Ok(match s {
1265 "i386" => I386,
1266 "i586" => I586,
1267 "i686" => I686,
1268 _ => return Err(()),
1269 })
1270 }
1271}
1272
1273impl FromStr for Mips32Architecture {
1274 type Err = ();
1275
1276 fn from_str(s: &str) -> Result<Self, ()> {
1277 use Mips32Architecture::*;
1278
1279 Ok(match s {
1280 "mips" => Mips,
1281 "mipsel" => Mipsel,
1282 "mipsisa32r6" => Mipsisa32r6,
1283 "mipsisa32r6el" => Mipsisa32r6el,
1284 _ => return Err(()),
1285 })
1286 }
1287}
1288
1289impl FromStr for Mips64Architecture {
1290 type Err = ();
1291
1292 fn from_str(s: &str) -> Result<Self, ()> {
1293 use Mips64Architecture::*;
1294
1295 Ok(match s {
1296 "mips64" => Mips64,
1297 "mips64el" => Mips64el,
1298 "mipsisa64r6" => Mipsisa64r6,
1299 "mipsisa64r6el" => Mipsisa64r6el,
1300 _ => return Err(()),
1301 })
1302 }
1303}
1304
1305impl FromStr for Architecture {
1306 type Err = ();
1307
1308 fn from_str(s: &str) -> Result<Self, ()> {
1309 use Architecture::*;
1310
1311 Ok(match s {
1312 "unknown" => Unknown,
1313 "amdgcn" => AmdGcn,
1314 "asmjs" => Asmjs,
1315 "avr" => Avr,
1316 "bpfeb" => Bpfeb,
1317 "bpfel" => Bpfel,
1318 "hexagon" => Hexagon,
1319 "loongarch64" => LoongArch64,
1320 "m68k" => M68k,
1321 "msp430" => Msp430,
1322 "nvptx64" => Nvptx64,
1323 "pulley32" => Pulley32,
1324 "pulley64" => Pulley64,
1325 "pulley32be" => Pulley32be,
1326 "pulley64be" => Pulley64be,
1327 "powerpc" => Powerpc,
1328 "powerpc64" => Powerpc64,
1329 "powerpc64le" => Powerpc64le,
1330 "s390x" => S390x,
1331 "sparc" => Sparc,
1332 "sparc64" => Sparc64,
1333 "sparcv9" => Sparcv9,
1334 "wasm32" => Wasm32,
1335 "wasm64" => Wasm64,
1336 "x86_64" => X86_64,
1337 "x86_64h" => X86_64h,
1338 "xtensa" => XTensa,
1339 #[cfg(feature = "arch_zkasm")]
1340 "zkasm" => ZkAsm,
1341 _ => {
1342 if let Ok(arm) = ArmArchitecture::from_str(s) {
1343 Arm(arm)
1344 } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) {
1345 Aarch64(aarch64)
1346 } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) {
1347 Riscv32(riscv32)
1348 } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) {
1349 Riscv64(riscv64)
1350 } else if let Ok(x86_32) = X86_32Architecture::from_str(s) {
1351 X86_32(x86_32)
1352 } else if let Ok(mips32) = Mips32Architecture::from_str(s) {
1353 Mips32(mips32)
1354 } else if let Ok(mips64) = Mips64Architecture::from_str(s) {
1355 Mips64(mips64)
1356 } else if let Ok(clever) = CleverArchitecture::from_str(s) {
1357 Clever(clever)
1358 } else {
1359 return Err(());
1360 }
1361 }
1362 })
1363 }
1364}
1365
1366impl fmt::Display for Vendor {
1367 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1368 f.write_str(self.as_str())
1369 }
1370}
1371
1372impl FromStr for Vendor {
1373 type Err = ();
1374
1375 fn from_str(s: &str) -> Result<Self, ()> {
1376 use Vendor::*;
1377
1378 Ok(match s {
1379 "unknown" => Unknown,
1380 "amd" => Amd,
1381 "apple" => Apple,
1382 "espressif" => Espressif,
1383 "experimental" => Experimental,
1384 "fortanix" => Fortanix,
1385 "ibm" => Ibm,
1386 "kmc" => Kmc,
1387 "nintendo" => Nintendo,
1388 "nvidia" => Nvidia,
1389 "pc" => Pc,
1390 "rumprun" => Rumprun,
1391 "sun" => Sun,
1392 "uwp" => Uwp,
1393 "wrs" => Wrs,
1394 custom => {
1395 #[cfg(not(feature = "std"))]
1396 use alloc::borrow::ToOwned;
1397
1398 if custom.is_empty() {
1405 return Err(());
1406 }
1407
1408 if Architecture::from_str(custom).is_ok()
1411 || OperatingSystem::from_str(custom).is_ok()
1412 || Environment::from_str(custom).is_ok()
1413 || BinaryFormat::from_str(custom).is_ok()
1414 {
1415 return Err(());
1416 }
1417
1418 if !custom.chars().next().unwrap().is_ascii_lowercase() {
1420 return Err(());
1421 }
1422
1423 let has_restricted = custom.chars().any(|c: char| {
1425 !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.')
1426 });
1427
1428 if has_restricted {
1429 return Err(());
1430 }
1431
1432 Custom(CustomVendor::Owned(Box::new(custom.to_owned())))
1433 }
1434 })
1435 }
1436}
1437
1438impl fmt::Display for OperatingSystem {
1439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1440 use OperatingSystem::*;
1441
1442 let mut with_version = |name, deployment_target| {
1443 if let Some(DeploymentTarget {
1444 major,
1445 minor,
1446 patch,
1447 }) = deployment_target
1448 {
1449 write!(f, "{}{}.{}.{}", name, major, minor, patch)
1450 } else {
1451 write!(f, "{}", name)
1452 }
1453 };
1454
1455 match *self {
1456 Darwin(deployment_target) => with_version("darwin", deployment_target),
1457 IOS(deployment_target) => with_version("ios", deployment_target),
1458 MacOSX(deployment_target) => with_version("macosx", deployment_target),
1459 TvOS(deployment_target) => with_version("tvos", deployment_target),
1460 VisionOS(deployment_target) => with_version("visionos", deployment_target),
1461 WatchOS(deployment_target) => with_version("watchos", deployment_target),
1462 XROS(deployment_target) => with_version("xros", deployment_target),
1463 os => f.write_str(&os.into_str()),
1464 }
1465 }
1466}
1467
1468impl FromStr for OperatingSystem {
1469 type Err = ();
1470
1471 fn from_str(s: &str) -> Result<Self, ()> {
1472 use OperatingSystem::*;
1473
1474 let parse_darwin = |name: &str| {
1475 let s = &s[name.len()..];
1476 let mut parts = s.split('.');
1477
1478 if s.is_empty() {
1479 return Ok(None);
1481 }
1482
1483 let major = if let Some(part) = parts.next() {
1484 part.parse().map_err(|_| ())?
1485 } else {
1486 return Err(());
1489 };
1490 let minor = if let Some(part) = parts.next() {
1491 part.parse().map_err(|_| ())?
1492 } else {
1493 0
1495 };
1496 let patch = if let Some(part) = parts.next() {
1497 part.parse().map_err(|_| ())?
1498 } else {
1499 0
1501 };
1502
1503 if parts.next().is_some() {
1504 return Err(());
1506 }
1507
1508 Ok(Some(DeploymentTarget {
1509 major,
1510 minor,
1511 patch,
1512 }))
1513 };
1514
1515 if s.starts_with("darwin") {
1517 return Ok(Darwin(parse_darwin("darwin")?));
1518 }
1519 if s.starts_with("ios") {
1520 return Ok(IOS(parse_darwin("ios")?));
1521 }
1522 if s.starts_with("macosx") {
1523 return Ok(MacOSX(parse_darwin("macosx")?));
1524 }
1525 if s.starts_with("tvos") {
1526 return Ok(TvOS(parse_darwin("tvos")?));
1527 }
1528 if s.starts_with("visionos") {
1529 return Ok(VisionOS(parse_darwin("visionos")?));
1530 }
1531 if s.starts_with("watchos") {
1532 return Ok(WatchOS(parse_darwin("watchos")?));
1533 }
1534 if s.starts_with("xros") {
1535 return Ok(XROS(parse_darwin("xros")?));
1536 }
1537
1538 Ok(match s {
1539 "unknown" => Unknown,
1540 "aix" => Aix,
1541 "amdhsa" => AmdHsa,
1542 "bitrig" => Bitrig,
1543 "cloudabi" => Cloudabi,
1544 "cuda" => Cuda,
1545 "dragonfly" => Dragonfly,
1546 "emscripten" => Emscripten,
1547 "freebsd" => Freebsd,
1548 "fuchsia" => Fuchsia,
1549 "haiku" => Haiku,
1550 "hermit" => Hermit,
1551 "horizon" => Horizon,
1552 "hurd" => Hurd,
1553 "illumos" => Illumos,
1554 "l4re" => L4re,
1555 "linux" => Linux,
1556 "nebulet" => Nebulet,
1557 "netbsd" => Netbsd,
1558 "none" => None_,
1559 "openbsd" => Openbsd,
1560 "psp" => Psp,
1561 "redox" => Redox,
1562 "solaris" => Solaris,
1563 "solid_asp3" => SolidAsp3,
1564 "uefi" => Uefi,
1565 "vxworks" => VxWorks,
1566 "wasi" => Wasi,
1567 "wasip1" => WasiP1,
1568 "wasip2" => WasiP2,
1569 "windows" => Windows,
1570 "espidf" => Espidf,
1571 _ => return Err(()),
1572 })
1573 }
1574}
1575
1576impl fmt::Display for Environment {
1577 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1578 f.write_str(&self.into_str())
1579 }
1580}
1581
1582impl FromStr for Environment {
1583 type Err = ();
1584
1585 fn from_str(s: &str) -> Result<Self, ()> {
1586 use Environment::*;
1587
1588 Ok(match s {
1589 "unknown" => Unknown,
1590 "amdgiz" => AmdGiz,
1591 "android" => Android,
1592 "androideabi" => Androideabi,
1593 "eabi" => Eabi,
1594 "eabihf" => Eabihf,
1595 "gnu" => Gnu,
1596 "gnuabi64" => Gnuabi64,
1597 "gnueabi" => Gnueabi,
1598 "gnueabihf" => Gnueabihf,
1599 "gnuspe" => Gnuspe,
1600 "gnux32" => Gnux32,
1601 "gnu_ilp32" => GnuIlp32,
1602 "gnullvm" => GnuLlvm,
1603 "hermitkernel" => HermitKernel,
1604 "hurdkernel" => HurdKernel,
1605 "linuxkernel" => LinuxKernel,
1606 "macabi" => Macabi,
1607 "musl" => Musl,
1608 "musleabi" => Musleabi,
1609 "musleabihf" => Musleabihf,
1610 "muslabi64" => Muslabi64,
1611 "msvc" => Msvc,
1612 "newlib" => Newlib,
1613 "none" => None,
1614 "kernel" => Kernel,
1615 "uclibc" => Uclibc,
1616 "uclibceabi" => Uclibceabi,
1617 "uclibceabihf" => Uclibceabihf,
1618 "sgx" => Sgx,
1619 "sim" => Sim,
1620 "softfloat" => Softfloat,
1621 "spe" => Spe,
1622 "threads" => Threads,
1623 "ohos" => Ohos,
1624 _ => return Err(()),
1625 })
1626 }
1627}
1628
1629impl fmt::Display for BinaryFormat {
1630 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1631 f.write_str(&self.into_str())
1632 }
1633}
1634
1635impl FromStr for BinaryFormat {
1636 type Err = ();
1637
1638 fn from_str(s: &str) -> Result<Self, ()> {
1639 use BinaryFormat::*;
1640
1641 Ok(match s {
1642 "unknown" => Unknown,
1643 "elf" => Elf,
1644 "coff" => Coff,
1645 "macho" => Macho,
1646 "wasm" => Wasm,
1647 "xcoff" => Xcoff,
1648 _ => return Err(()),
1649 })
1650 }
1651}
1652
1653#[cfg(test)]
1654mod tests {
1655 use super::*;
1656 use alloc::string::ToString;
1657
1658 #[test]
1659 fn roundtrip_known_triples() {
1660 let targets = [
1665 "aarch64-apple-darwin",
1666 "aarch64-apple-ios",
1667 "aarch64-apple-ios-macabi",
1668 "aarch64-apple-ios-sim",
1669 "aarch64-apple-tvos",
1670 "aarch64-apple-tvos-sim",
1671 "aarch64-apple-visionos",
1672 "aarch64-apple-visionos-sim",
1673 "aarch64-apple-watchos",
1674 "aarch64-apple-watchos-sim",
1675 "aarch64_be-unknown-linux-gnu",
1676 "aarch64_be-unknown-linux-gnu_ilp32",
1677 "aarch64_be-unknown-netbsd",
1678 "aarch64-kmc-solid_asp3",
1679 "aarch64-linux-android",
1680 "aarch64-pc-windows-gnullvm",
1682 "aarch64-pc-windows-msvc",
1683 "aarch64-unknown-cloudabi",
1684 "aarch64-unknown-freebsd",
1685 "aarch64-unknown-fuchsia",
1686 "aarch64-unknown-hermit",
1687 "aarch64-unknown-illumos",
1688 "aarch64-unknown-linux-gnu",
1689 "aarch64-unknown-linux-gnu_ilp32",
1690 "aarch64-unknown-linux-musl",
1691 "aarch64-unknown-linux-ohos",
1692 "aarch64-unknown-netbsd",
1693 "aarch64-unknown-none",
1694 "aarch64-unknown-none-softfloat",
1695 "aarch64-unknown-openbsd",
1697 "aarch64-unknown-redox",
1698 "aarch64-unknown-uefi",
1700 "aarch64-uwp-windows-msvc",
1701 "aarch64-wrs-vxworks",
1702 "amdgcn-amd-amdhsa",
1705 "amdgcn-amd-amdhsa-amdgiz",
1706 "armeb-unknown-linux-gnueabi",
1709 "armebv7r-none-eabi",
1710 "armebv7r-none-eabihf",
1711 "arm-linux-androideabi",
1712 "arm-unknown-linux-gnueabi",
1713 "arm-unknown-linux-gnueabihf",
1714 "arm-unknown-linux-musleabi",
1715 "arm-unknown-linux-musleabihf",
1716 "armv4t-none-eabi",
1717 "armv4t-unknown-linux-gnueabi",
1718 "armv5te-none-eabi",
1719 "armv5te-unknown-linux-gnueabi",
1720 "armv5te-unknown-linux-musleabi",
1721 "armv5te-unknown-linux-uclibceabi",
1722 "armv6k-nintendo-3ds",
1723 "armv6-unknown-freebsd",
1724 "armv6-unknown-netbsd-eabihf",
1725 "armv7a-kmc-solid_asp3-eabi",
1726 "armv7a-kmc-solid_asp3-eabihf",
1727 "armv7a-none-eabi",
1728 "armv7a-none-eabihf",
1729 "armv7-apple-ios",
1730 "armv7k-apple-watchos",
1731 "armv7-linux-androideabi",
1732 "armv7r-none-eabi",
1733 "armv7r-none-eabihf",
1734 "armv7s-apple-ios",
1735 "armv7-unknown-cloudabi-eabihf",
1736 "armv7-unknown-freebsd",
1738 "armv7-unknown-linux-gnueabi",
1739 "armv7-unknown-linux-gnueabihf",
1740 "armv7-unknown-linux-musleabi",
1741 "armv7-unknown-linux-musleabihf",
1742 "armv7-unknown-linux-ohos",
1743 "armv7-unknown-linux-uclibceabi",
1744 "armv7-unknown-linux-uclibceabihf",
1745 "armv7-unknown-netbsd-eabihf",
1746 "armv7-wrs-vxworks-eabihf",
1747 "asmjs-unknown-emscripten",
1748 "armv8r-none-eabihf",
1749 "avr-unknown-unknown",
1751 "bpfeb-unknown-none",
1752 "bpfel-unknown-none",
1753 "hexagon-unknown-linux-musl",
1756 "hexagon-unknown-none-elf",
1757 "i386-apple-ios",
1758 "i586-pc-windows-msvc",
1760 "i586-unknown-linux-gnu",
1761 "i586-unknown-linux-musl",
1762 "i586-unknown-netbsd",
1763 "i686-apple-darwin",
1764 "i686-linux-android",
1765 "i686-apple-macosx10.7.0",
1766 "i686-pc-windows-gnu",
1767 "i686-pc-windows-gnullvm",
1768 "i686-pc-windows-msvc",
1769 "i686-unknown-cloudabi",
1770 "i686-unknown-dragonfly",
1771 "i686-unknown-freebsd",
1772 "i686-unknown-haiku",
1773 "i686-unknown-hurd-gnu",
1774 "i686-unknown-linux-gnu",
1775 "i686-unknown-linux-musl",
1776 "i686-unknown-netbsd",
1777 "i686-unknown-openbsd",
1778 "i686-unknown-redox",
1779 "i686-unknown-uefi",
1780 "i686-uwp-windows-gnu",
1781 "i686-uwp-windows-msvc",
1782 "i686-win7-windows-msvc",
1783 "i686-wrs-vxworks",
1784 "loongarch64-unknown-linux-gnu",
1785 "loongarch64-unknown-linux-musl",
1786 "loongarch64-unknown-none",
1787 "loongarch64-unknown-none-softfloat",
1788 "m68k-unknown-linux-gnu",
1789 "mips64el-unknown-linux-gnuabi64",
1790 "mips64el-unknown-linux-muslabi64",
1791 "mips64-openwrt-linux-musl",
1792 "mips64-unknown-linux-gnuabi64",
1793 "mips64-unknown-linux-muslabi64",
1794 "mipsel-sony-psp",
1795 "mipsel-unknown-linux-gnu",
1797 "mipsel-unknown-linux-musl",
1798 "mipsel-unknown-linux-uclibc",
1799 "mipsel-unknown-netbsd",
1800 "mipsel-unknown-none",
1801 "mipsisa32r6el-unknown-linux-gnu",
1802 "mipsisa32r6-unknown-linux-gnu",
1803 "mipsisa64r6el-unknown-linux-gnuabi64",
1804 "mipsisa64r6-unknown-linux-gnuabi64",
1805 "mips-unknown-linux-gnu",
1806 "mips-unknown-linux-musl",
1807 "mips-unknown-linux-uclibc",
1808 "msp430-none-elf",
1809 "nvptx64-nvidia-cuda",
1810 "powerpc64-ibm-aix",
1811 "powerpc64le-unknown-freebsd",
1812 "powerpc64le-unknown-linux-gnu",
1813 "powerpc64le-unknown-linux-musl",
1814 "powerpc64-unknown-freebsd",
1815 "powerpc64-unknown-linux-gnu",
1816 "powerpc64-unknown-linux-musl",
1817 "powerpc64-unknown-openbsd",
1818 "powerpc64-wrs-vxworks",
1819 "powerpc-ibm-aix",
1820 "powerpc-unknown-freebsd",
1821 "powerpc-unknown-linux-gnu",
1822 "powerpc-unknown-linux-gnuspe",
1823 "powerpc-unknown-linux-musl",
1824 "powerpc-unknown-netbsd",
1825 "powerpc-unknown-openbsd",
1826 "powerpc-wrs-vxworks",
1827 "powerpc-wrs-vxworks-spe",
1828 "riscv32gc-unknown-linux-gnu",
1829 "riscv32gc-unknown-linux-musl",
1830 "riscv32imac-esp-espidf",
1831 "riscv32imac-unknown-none-elf",
1832 "riscv32imafc-esp-espidf",
1834 "riscv32imafc-unknown-none-elf",
1835 "riscv32ima-unknown-none-elf",
1836 "riscv32imc-esp-espidf",
1837 "riscv32imc-unknown-none-elf",
1838 "riscv32im-unknown-none-elf",
1840 "riscv32i-unknown-none-elf",
1841 "riscv64gc-unknown-freebsd",
1842 "riscv64gc-unknown-fuchsia",
1843 "riscv64gc-unknown-hermit",
1844 "riscv64gc-unknown-linux-gnu",
1845 "riscv64gc-unknown-linux-musl",
1846 "riscv64gc-unknown-netbsd",
1847 "riscv64gc-unknown-none-elf",
1848 "riscv64gc-unknown-openbsd",
1849 "riscv64imac-unknown-none-elf",
1850 "riscv64-linux-android",
1851 "s390x-unknown-linux-gnu",
1852 "s390x-unknown-linux-musl",
1853 "sparc64-unknown-linux-gnu",
1854 "sparc64-unknown-netbsd",
1855 "sparc64-unknown-openbsd",
1856 "sparc-unknown-linux-gnu",
1857 "sparc-unknown-none-elf",
1858 "sparcv9-sun-solaris",
1859 "thumbv4t-none-eabi",
1860 "thumbv5te-none-eabi",
1861 "thumbv6m-none-eabi",
1862 "thumbv7a-pc-windows-msvc",
1863 "thumbv7a-uwp-windows-msvc",
1864 "thumbv7em-none-eabi",
1865 "thumbv7em-none-eabihf",
1866 "thumbv7m-none-eabi",
1867 "thumbv7neon-linux-androideabi",
1868 "thumbv7neon-unknown-linux-gnueabihf",
1869 "thumbv7neon-unknown-linux-musleabihf",
1870 "thumbv8m.base-none-eabi",
1871 "thumbv8m.main-none-eabi",
1872 "thumbv8m.main-none-eabihf",
1873 "wasm32-experimental-emscripten",
1874 "wasm32-unknown-emscripten",
1875 "wasm32-unknown-unknown",
1876 "wasm32-wasi",
1877 "wasm32-wasip1",
1878 "wasm32-wasip1-threads",
1879 "wasm32-wasip2",
1880 "wasm64-unknown-unknown",
1881 "wasm64-wasi",
1882 "x86_64-apple-darwin",
1883 "x86_64-apple-darwin23.6.0",
1884 "x86_64-apple-ios",
1885 "x86_64-apple-ios-macabi",
1886 "x86_64-apple-tvos",
1887 "x86_64-apple-watchos-sim",
1888 "x86_64-fortanix-unknown-sgx",
1889 "x86_64h-apple-darwin",
1890 "x86_64-linux-android",
1891 "x86_64-linux-kernel", "x86_64-apple-macosx",
1894 "x86_64-apple-macosx10.7.0",
1895 "x86_64-pc-solaris",
1896 "x86_64-pc-windows-gnu",
1897 "x86_64-pc-windows-gnullvm",
1898 "x86_64-pc-windows-msvc",
1899 "x86_64-rumprun-netbsd", "x86_64-sun-solaris",
1901 "x86_64-unknown-bitrig",
1902 "x86_64-unknown-cloudabi",
1903 "x86_64-unikraft-linux-musl",
1904 "x86_64-unknown-dragonfly",
1905 "x86_64-unknown-freebsd",
1906 "x86_64-unknown-fuchsia",
1907 "x86_64-unknown-haiku",
1908 "x86_64-unknown-hermit-kernel", "x86_64-unknown-hermit",
1910 "x86_64-unknown-illumos",
1911 "x86_64-unknown-l4re-uclibc",
1912 "x86_64-unknown-linux-gnu",
1913 "x86_64-unknown-linux-gnux32",
1914 "x86_64-unknown-linux-musl",
1915 "x86_64-unknown-linux-none",
1916 "x86_64-unknown-linux-ohos",
1917 "x86_64-unknown-netbsd",
1918 "x86_64-unknown-none",
1919 "x86_64-unknown-none-hermitkernel",
1920 "x86_64-unknown-none-linuxkernel",
1921 "x86_64-unknown-openbsd",
1922 "x86_64-unknown-redox",
1923 "x86_64-unknown-uefi",
1924 "x86_64-uwp-windows-gnu",
1925 "x86_64-uwp-windows-msvc",
1926 "x86_64-win7-windows-msvc",
1927 "x86_64-wrs-vxworks",
1928 "xtensa-esp32-espidf",
1929 "clever-unknown-elf",
1930 "xtensa-esp32-none-elf",
1931 "xtensa-esp32s2-espidf",
1932 "xtensa-esp32s2-none-elf",
1933 "xtensa-esp32s3-espidf",
1934 "xtensa-esp32s3-none-elf",
1935 #[cfg(feature = "arch_zkasm")]
1936 "zkasm-unknown-unknown",
1937 ];
1938
1939 for target in targets.iter() {
1940 let t = Triple::from_str(target).expect("can't parse target");
1941 assert_ne!(t.architecture, Architecture::Unknown);
1942 assert_eq!(t.to_string(), *target, "{:#?}", t);
1943 }
1944 }
1945
1946 #[test]
1947 fn default_format_to_elf() {
1948 let t = Triple::from_str("riscv64").expect("can't parse target");
1949 assert_eq!(
1950 t.architecture,
1951 Architecture::Riscv64(Riscv64Architecture::Riscv64),
1952 );
1953 assert_eq!(t.vendor, Vendor::Unknown);
1954 assert_eq!(t.operating_system, OperatingSystem::Unknown);
1955 assert_eq!(t.environment, Environment::Unknown);
1956 assert_eq!(t.binary_format, BinaryFormat::Elf);
1957 }
1958
1959 #[test]
1960 fn thumbv7em_none_eabihf() {
1961 let t = Triple::from_str("thumbv7em-none-eabihf").expect("can't parse target");
1962 assert_eq!(
1963 t.architecture,
1964 Architecture::Arm(ArmArchitecture::Thumbv7em)
1965 );
1966 assert_eq!(t.vendor, Vendor::Unknown);
1967 assert_eq!(t.operating_system, OperatingSystem::None_);
1968 assert_eq!(t.environment, Environment::Eabihf);
1969 assert_eq!(t.binary_format, BinaryFormat::Elf);
1970 }
1971
1972 #[test]
1973 fn fuchsia_rename() {
1974 assert_eq!(
1976 Triple::from_str("aarch64-fuchsia"),
1977 Triple::from_str("aarch64-unknown-fuchsia")
1978 );
1979 assert_eq!(
1980 Triple::from_str("x86_64-fuchsia"),
1981 Triple::from_str("x86_64-unknown-fuchsia")
1982 );
1983 }
1984
1985 #[test]
1986 fn custom_vendors() {
1987 assert!(Triple::from_str("x86_64--linux").is_err());
1989 assert!(Triple::from_str("x86_64-42-linux").is_err());
1990 assert!(Triple::from_str("x86_64-__customvendor__-linux").is_err());
1991 assert!(Triple::from_str("x86_64-^-linux").is_err());
1992 assert!(Triple::from_str("x86_64- -linux").is_err());
1993 assert!(Triple::from_str("x86_64-CustomVendor-linux").is_err());
1994 assert!(Triple::from_str("x86_64-linux-linux").is_err());
1995 assert!(Triple::from_str("x86_64-x86_64-linux").is_err());
1996 assert!(Triple::from_str("x86_64-elf-linux").is_err());
1997 assert!(Triple::from_str("x86_64-gnu-linux").is_err());
1998 assert!(Triple::from_str("x86_64-linux-customvendor").is_err());
1999 assert!(Triple::from_str("customvendor").is_err());
2000 assert!(Triple::from_str("customvendor-x86_64").is_err());
2001 assert!(Triple::from_str("x86_64-").is_err());
2002 assert!(Triple::from_str("x86_64--").is_err());
2003
2004 assert!(
2006 Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux").is_err(),
2007 "unicode font hazard"
2008 );
2009 assert!(
2010 Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux").is_err(),
2011 "diacritical mark stripping hazard"
2012 );
2013 assert!(
2014 Triple::from_str("x86_64-customvendοr-linux").is_err(),
2015 "homoglyph hazard"
2016 );
2017 assert!(Triple::from_str("x86_64-customvendor-linux").is_ok());
2018 assert!(
2019 Triple::from_str("x86_64-ffi-linux").is_err(),
2020 "normalization hazard"
2021 );
2022 assert!(Triple::from_str("x86_64-ffi-linux").is_ok());
2023 assert!(
2024 Triple::from_str("x86_64-customvendor-linux").is_err(),
2025 "zero-width character hazard"
2026 );
2027 assert!(
2028 Triple::from_str("x86_64-customvendor-linux").is_err(),
2029 "BOM hazard"
2030 );
2031
2032 let t = Triple::from_str("x86_64-customvendor-linux")
2034 .expect("can't parse target with custom vendor");
2035 assert_eq!(t.architecture, Architecture::X86_64);
2036 assert_eq!(
2037 t.vendor,
2038 Vendor::Custom(CustomVendor::Static("customvendor"))
2039 );
2040 assert_eq!(t.operating_system, OperatingSystem::Linux);
2041 assert_eq!(t.environment, Environment::Unknown);
2042 assert_eq!(t.binary_format, BinaryFormat::Elf);
2043 assert_eq!(t.to_string(), "x86_64-customvendor-linux");
2044
2045 let t =
2046 Triple::from_str("x86_64-customvendor").expect("can't parse target with custom vendor");
2047 assert_eq!(t.architecture, Architecture::X86_64);
2048 assert_eq!(
2049 t.vendor,
2050 Vendor::Custom(CustomVendor::Static("customvendor"))
2051 );
2052 assert_eq!(t.operating_system, OperatingSystem::Unknown);
2053 assert_eq!(t.environment, Environment::Unknown);
2054 assert_eq!(t.binary_format, BinaryFormat::Elf);
2055
2056 assert_eq!(
2057 Triple::from_str("unknown-foo"),
2058 Ok(Triple {
2059 architecture: Architecture::Unknown,
2060 vendor: Vendor::Custom(CustomVendor::Static("foo")),
2061 operating_system: OperatingSystem::Unknown,
2062 environment: Environment::Unknown,
2063 binary_format: BinaryFormat::Unknown,
2064 })
2065 );
2066 }
2067
2068 #[test]
2069 fn deployment_version_parsing() {
2070 assert_eq!(
2071 Triple::from_str("aarch64-apple-macosx"),
2072 Ok(Triple {
2073 architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
2074 vendor: Vendor::Apple,
2075 operating_system: OperatingSystem::MacOSX(None),
2076 environment: Environment::Unknown,
2077 binary_format: BinaryFormat::Macho,
2078 })
2079 );
2080
2081 assert_eq!(
2082 Triple::from_str("aarch64-apple-macosx10.14.6"),
2083 Ok(Triple {
2084 architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64),
2085 vendor: Vendor::Apple,
2086 operating_system: OperatingSystem::MacOSX(Some(DeploymentTarget {
2087 major: 10,
2088 minor: 14,
2089 patch: 6,
2090 })),
2091 environment: Environment::Unknown,
2092 binary_format: BinaryFormat::Macho,
2093 })
2094 );
2095
2096 let expected = Triple {
2097 architecture: Architecture::X86_64,
2098 vendor: Vendor::Apple,
2099 operating_system: OperatingSystem::Darwin(Some(DeploymentTarget {
2100 major: 23,
2101 minor: 0,
2102 patch: 0,
2103 })),
2104 environment: Environment::Unknown,
2105 binary_format: BinaryFormat::Macho,
2106 };
2107 assert_eq!(
2108 Triple::from_str("x86_64-apple-darwin23"),
2109 Ok(expected.clone())
2110 );
2111 assert_eq!(
2112 Triple::from_str("x86_64-apple-darwin23.0"),
2113 Ok(expected.clone())
2114 );
2115 assert_eq!(Triple::from_str("x86_64-apple-darwin23.0.0"), Ok(expected));
2116
2117 assert!(Triple::from_str("x86_64-apple-darwin.").is_err());
2118 assert!(Triple::from_str("x86_64-apple-darwin23.0.0.0").is_err());
2119 }
2120}