Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/target-lexicon-0.12.15/src/targets.rs
Line
Count
Source (jump to first uncovered line)
1
// This file defines all the identifier enums and target-aware logic.
2
3
use crate::triple::{Endianness, PointerWidth, Triple};
4
use alloc::borrow::Cow;
5
use alloc::boxed::Box;
6
use alloc::format;
7
use alloc::string::String;
8
use core::fmt;
9
use core::hash::{Hash, Hasher};
10
use core::str::FromStr;
11
12
/// The "architecture" field, which in some cases also specifies a specific
13
/// subarchitecture.
14
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
15
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
16
#[allow(missing_docs)]
17
pub 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
    Powerpc,
35
    Powerpc64,
36
    Powerpc64le,
37
    Riscv32(Riscv32Architecture),
38
    Riscv64(Riscv64Architecture),
39
    S390x,
40
    Sparc,
41
    Sparc64,
42
    Sparcv9,
43
    Wasm32,
44
    Wasm64,
45
    X86_64,
46
    /// x86_64 target that only supports Haswell-compatible Intel chips.
47
    X86_64h,
48
    XTensa,
49
    Clever(CleverArchitecture),
50
    /// A software machine that produces zero-knowledge proofs of the execution.
51
    ///
52
    /// See https://wiki.polygon.technology/docs/category/zk-assembly/
53
    #[cfg(feature = "arch_zkasm")]
54
    ZkAsm,
55
}
56
57
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
58
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
59
#[allow(missing_docs)]
60
pub enum ArmArchitecture {
61
    Arm, // Generic arm
62
    Armeb,
63
    Armv4,
64
    Armv4t,
65
    Armv5t,
66
    Armv5te,
67
    Armv5tej,
68
    Armv6,
69
    Armv6j,
70
    Armv6k,
71
    Armv6z,
72
    Armv6kz,
73
    Armv6t2,
74
    Armv6m,
75
    Armv7,
76
    Armv7a,
77
    Armv7k,
78
    Armv7ve,
79
    Armv7m,
80
    Armv7r,
81
    Armv7s,
82
    Armv8,
83
    Armv8a,
84
    Armv8_1a,
85
    Armv8_2a,
86
    Armv8_3a,
87
    Armv8_4a,
88
    Armv8_5a,
89
    Armv8mBase,
90
    Armv8mMain,
91
    Armv8r,
92
93
    Armebv7r,
94
95
    Thumbeb,
96
    Thumbv4t,
97
    Thumbv5te,
98
    Thumbv6m,
99
    Thumbv7a,
100
    Thumbv7em,
101
    Thumbv7m,
102
    Thumbv7neon,
103
    Thumbv8mBase,
104
    Thumbv8mMain,
105
}
106
107
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
108
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
109
#[allow(missing_docs)]
110
pub enum Aarch64Architecture {
111
    Aarch64,
112
    Aarch64be,
113
}
114
115
// #[cfg_attr(feature = "rust_1_40", non_exhaustive)]
116
// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
117
// #[allow(missing_docs)]
118
// pub enum ArmFpu {
119
//     Vfp,
120
//     Vfpv2,
121
//     Vfpv3,
122
//     Vfpv3Fp16,
123
//     Vfpv3Xd,
124
//     Vfpv3XdFp16,
125
//     Neon,
126
//     NeonVfpv3,
127
//     NeonVfpv4,
128
//     Vfpv4,
129
//     Vfpv4D16,
130
//     Fpv4SpD16,
131
//     Fpv5SpD16,
132
//     Fpv5D16,
133
//     FpArmv8,
134
//     NeonFpArmv8,
135
//     CryptoNeonFpArmv8,
136
// }
137
138
impl ArmArchitecture {
139
    /// Test if this architecture uses the Thumb instruction set.
140
    #[rustfmt::skip]
141
0
    pub fn is_thumb(self) -> bool {
142
0
        use ArmArchitecture::*;
143
0
144
0
        match self {
145
            Arm
146
            | Armeb
147
            | Armv4
148
            | Armv4t
149
            | Armv5t
150
            | Armv5te
151
            | Armv5tej
152
            | Armv6
153
            | Armv6j
154
            | Armv6k
155
            | Armv6z
156
            | Armv6kz
157
            | Armv6t2
158
            | Armv6m
159
            | Armv7
160
            | Armv7a
161
            | Armv7k
162
            | Armv7ve
163
            | Armv7m
164
            | Armv7r
165
            | Armv7s
166
            | Armv8
167
            | Armv8a
168
            | Armv8_1a
169
            | Armv8_2a
170
            | Armv8_3a
171
            | Armv8_4a
172
            | Armv8_5a
173
            | Armv8mBase
174
            | Armv8mMain
175
            | Armv8r
176
0
            | Armebv7r => false,
177
            Thumbeb
178
            | Thumbv4t
179
            | Thumbv5te
180
            | Thumbv6m
181
            | Thumbv7a
182
            | Thumbv7em
183
            | Thumbv7m
184
            | Thumbv7neon
185
            | Thumbv8mBase
186
0
            | Thumbv8mMain => true,
187
        }
188
0
    }
189
190
    // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
191
192
    // }
193
194
    /// Return the pointer bit width of this target's architecture.
195
    #[rustfmt::skip]
196
0
    pub fn pointer_width(self) -> PointerWidth {
197
0
        use ArmArchitecture::*;
198
0
199
0
        match self {
200
            Arm
201
            | Armeb
202
            | Armv4
203
            | Armv4t
204
            | Armv5t
205
            | Armv5te
206
            | Armv5tej
207
            | Armv6
208
            | Armv6j
209
            | Armv6k
210
            | Armv6z
211
            | Armv6kz
212
            | Armv6t2
213
            | Armv6m
214
            | Armv7
215
            | Armv7a
216
            | Armv7k
217
            | Armv7ve
218
            | Armv7m
219
            | Armv7r
220
            | Armv7s
221
            | Armv8
222
            | Armv8a
223
            | Armv8_1a
224
            | Armv8_2a
225
            | Armv8_3a
226
            | Armv8_4a
227
            | Armv8_5a
228
            | Armv8mBase
229
            | Armv8mMain
230
            | Armv8r
231
            | Armebv7r
232
            | Thumbeb
233
            | Thumbv4t
234
            | Thumbv5te
235
            | Thumbv6m
236
            | Thumbv7a
237
            | Thumbv7em
238
            | Thumbv7m
239
            | Thumbv7neon
240
            | Thumbv8mBase
241
0
            | Thumbv8mMain => PointerWidth::U32,
242
0
        }
243
0
    }
244
245
    /// Return the endianness of this architecture.
246
    #[rustfmt::skip]
247
0
    pub fn endianness(self) -> Endianness {
248
0
        use ArmArchitecture::*;
249
0
250
0
        match self {
251
            Arm
252
            | Armv4
253
            | Armv4t
254
            | Armv5t
255
            | Armv5te
256
            | Armv5tej
257
            | Armv6
258
            | Armv6j
259
            | Armv6k
260
            | Armv6z
261
            | Armv6kz
262
            | Armv6t2
263
            | Armv6m
264
            | Armv7
265
            | Armv7a
266
            | Armv7k
267
            | Armv7ve
268
            | Armv7m
269
            | Armv7r
270
            | Armv7s
271
            | Armv8
272
            | Armv8a
273
            | Armv8_1a
274
            | Armv8_2a
275
            | Armv8_3a
276
            | Armv8_4a
277
            | Armv8_5a
278
            | Armv8mBase
279
            | Armv8mMain
280
            | Armv8r
281
            | Thumbv4t
282
            | Thumbv5te
283
            | Thumbv6m
284
            | Thumbv7a
285
            | Thumbv7em
286
            | Thumbv7m
287
            | Thumbv7neon
288
            | Thumbv8mBase
289
0
            | Thumbv8mMain => Endianness::Little,
290
0
            Armeb | Armebv7r | Thumbeb => Endianness::Big,
291
        }
292
0
    }
293
294
    /// Convert into a string
295
0
    pub fn into_str(self) -> Cow<'static, str> {
296
0
        use ArmArchitecture::*;
297
0
298
0
        match self {
299
0
            Arm => Cow::Borrowed("arm"),
300
0
            Armeb => Cow::Borrowed("armeb"),
301
0
            Armv4 => Cow::Borrowed("armv4"),
302
0
            Armv4t => Cow::Borrowed("armv4t"),
303
0
            Armv5t => Cow::Borrowed("armv5t"),
304
0
            Armv5te => Cow::Borrowed("armv5te"),
305
0
            Armv5tej => Cow::Borrowed("armv5tej"),
306
0
            Armv6 => Cow::Borrowed("armv6"),
307
0
            Armv6j => Cow::Borrowed("armv6j"),
308
0
            Armv6k => Cow::Borrowed("armv6k"),
309
0
            Armv6z => Cow::Borrowed("armv6z"),
310
0
            Armv6kz => Cow::Borrowed("armv6kz"),
311
0
            Armv6t2 => Cow::Borrowed("armv6t2"),
312
0
            Armv6m => Cow::Borrowed("armv6m"),
313
0
            Armv7 => Cow::Borrowed("armv7"),
314
0
            Armv7a => Cow::Borrowed("armv7a"),
315
0
            Armv7k => Cow::Borrowed("armv7k"),
316
0
            Armv7ve => Cow::Borrowed("armv7ve"),
317
0
            Armv7m => Cow::Borrowed("armv7m"),
318
0
            Armv7r => Cow::Borrowed("armv7r"),
319
0
            Armv7s => Cow::Borrowed("armv7s"),
320
0
            Armv8 => Cow::Borrowed("armv8"),
321
0
            Armv8a => Cow::Borrowed("armv8a"),
322
0
            Armv8_1a => Cow::Borrowed("armv8.1a"),
323
0
            Armv8_2a => Cow::Borrowed("armv8.2a"),
324
0
            Armv8_3a => Cow::Borrowed("armv8.3a"),
325
0
            Armv8_4a => Cow::Borrowed("armv8.4a"),
326
0
            Armv8_5a => Cow::Borrowed("armv8.5a"),
327
0
            Armv8mBase => Cow::Borrowed("armv8m.base"),
328
0
            Armv8mMain => Cow::Borrowed("armv8m.main"),
329
0
            Armv8r => Cow::Borrowed("armv8r"),
330
0
            Thumbeb => Cow::Borrowed("thumbeb"),
331
0
            Thumbv4t => Cow::Borrowed("thumbv4t"),
332
0
            Thumbv5te => Cow::Borrowed("thumbv5te"),
333
0
            Thumbv6m => Cow::Borrowed("thumbv6m"),
334
0
            Thumbv7a => Cow::Borrowed("thumbv7a"),
335
0
            Thumbv7em => Cow::Borrowed("thumbv7em"),
336
0
            Thumbv7m => Cow::Borrowed("thumbv7m"),
337
0
            Thumbv7neon => Cow::Borrowed("thumbv7neon"),
338
0
            Thumbv8mBase => Cow::Borrowed("thumbv8m.base"),
339
0
            Thumbv8mMain => Cow::Borrowed("thumbv8m.main"),
340
0
            Armebv7r => Cow::Borrowed("armebv7r"),
341
        }
342
0
    }
343
}
344
345
impl Aarch64Architecture {
346
    /// Test if this architecture uses the Thumb instruction set.
347
0
    pub fn is_thumb(self) -> bool {
348
0
        match self {
349
0
            Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false,
350
0
        }
351
0
    }
352
353
    // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
354
355
    // }
356
357
    /// Return the pointer bit width of this target's architecture.
358
    ///
359
    /// This function is only aware of the CPU architecture so it is not aware
360
    /// of ilp32 ABIs.
361
0
    pub fn pointer_width(self) -> PointerWidth {
362
0
        match self {
363
0
            Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64,
364
0
        }
365
0
    }
366
367
    /// Return the endianness of this architecture.
368
0
    pub fn endianness(self) -> Endianness {
369
0
        match self {
370
0
            Aarch64Architecture::Aarch64 => Endianness::Little,
371
0
            Aarch64Architecture::Aarch64be => Endianness::Big,
372
        }
373
0
    }
374
375
    /// Convert into a string
376
0
    pub fn into_str(self) -> Cow<'static, str> {
377
0
        use Aarch64Architecture::*;
378
0
379
0
        match self {
380
0
            Aarch64 => Cow::Borrowed("aarch64"),
381
0
            Aarch64be => Cow::Borrowed("aarch64_be"),
382
        }
383
0
    }
384
}
385
386
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
387
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
388
#[allow(missing_docs)]
389
pub enum CleverArchitecture {
390
    Clever,
391
    Clever1_0,
392
}
393
394
impl CleverArchitecture {
395
    /// Convert into a string
396
0
    pub fn into_str(self) -> Cow<'static, str> {
397
0
        use CleverArchitecture::*;
398
0
399
0
        match self {
400
0
            Clever => Cow::Borrowed("clever"),
401
0
            Clever1_0 => Cow::Borrowed("clever1.0"),
402
        }
403
0
    }
404
}
405
406
/// An enum for all 32-bit RISC-V architectures.
407
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
408
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
409
#[allow(missing_docs)]
410
pub enum Riscv32Architecture {
411
    Riscv32,
412
    Riscv32gc,
413
    Riscv32i,
414
    Riscv32im,
415
    Riscv32ima,
416
    Riscv32imac,
417
    Riscv32imafc,
418
    Riscv32imc,
419
}
420
421
impl Riscv32Architecture {
422
    /// Convert into a string
423
0
    pub fn into_str(self) -> Cow<'static, str> {
424
0
        use Riscv32Architecture::*;
425
0
426
0
        match self {
427
0
            Riscv32 => Cow::Borrowed("riscv32"),
428
0
            Riscv32gc => Cow::Borrowed("riscv32gc"),
429
0
            Riscv32i => Cow::Borrowed("riscv32i"),
430
0
            Riscv32im => Cow::Borrowed("riscv32im"),
431
0
            Riscv32ima => Cow::Borrowed("riscv32ima"),
432
0
            Riscv32imac => Cow::Borrowed("riscv32imac"),
433
0
            Riscv32imafc => Cow::Borrowed("riscv32imafc"),
434
0
            Riscv32imc => Cow::Borrowed("riscv32imc"),
435
        }
436
0
    }
437
}
438
439
/// An enum for all 64-bit RISC-V architectures.
440
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
441
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
442
#[allow(missing_docs)]
443
pub enum Riscv64Architecture {
444
    Riscv64,
445
    Riscv64gc,
446
    Riscv64imac,
447
}
448
449
impl Riscv64Architecture {
450
    /// Convert into a string
451
0
    pub fn into_str(self) -> Cow<'static, str> {
452
0
        use Riscv64Architecture::*;
453
0
454
0
        match self {
455
0
            Riscv64 => Cow::Borrowed("riscv64"),
456
0
            Riscv64gc => Cow::Borrowed("riscv64gc"),
457
0
            Riscv64imac => Cow::Borrowed("riscv64imac"),
458
        }
459
0
    }
460
}
461
462
/// An enum for all 32-bit x86 architectures.
463
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
464
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
465
#[allow(missing_docs)]
466
pub enum X86_32Architecture {
467
    I386,
468
    I586,
469
    I686,
470
}
471
472
impl X86_32Architecture {
473
    /// Convert into a string
474
0
    pub fn into_str(self) -> Cow<'static, str> {
475
0
        use X86_32Architecture::*;
476
0
477
0
        match self {
478
0
            I386 => Cow::Borrowed("i386"),
479
0
            I586 => Cow::Borrowed("i586"),
480
0
            I686 => Cow::Borrowed("i686"),
481
        }
482
0
    }
483
}
484
485
/// An enum for all 32-bit MIPS architectures (not just "MIPS32").
486
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
487
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
488
#[allow(missing_docs)]
489
pub enum Mips32Architecture {
490
    Mips,
491
    Mipsel,
492
    Mipsisa32r6,
493
    Mipsisa32r6el,
494
}
495
496
impl Mips32Architecture {
497
    /// Convert into a string
498
0
    pub fn into_str(self) -> Cow<'static, str> {
499
0
        use Mips32Architecture::*;
500
0
501
0
        match self {
502
0
            Mips => Cow::Borrowed("mips"),
503
0
            Mipsel => Cow::Borrowed("mipsel"),
504
0
            Mipsisa32r6 => Cow::Borrowed("mipsisa32r6"),
505
0
            Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el"),
506
        }
507
0
    }
508
}
509
510
/// An enum for all 64-bit MIPS architectures (not just "MIPS64").
511
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
512
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
513
#[allow(missing_docs)]
514
pub enum Mips64Architecture {
515
    Mips64,
516
    Mips64el,
517
    Mipsisa64r6,
518
    Mipsisa64r6el,
519
}
520
521
impl Mips64Architecture {
522
    /// Convert into a string
523
0
    pub fn into_str(self) -> Cow<'static, str> {
524
0
        use Mips64Architecture::*;
525
0
526
0
        match self {
527
0
            Mips64 => Cow::Borrowed("mips64"),
528
0
            Mips64el => Cow::Borrowed("mips64el"),
529
0
            Mipsisa64r6 => Cow::Borrowed("mipsisa64r6"),
530
0
            Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el"),
531
        }
532
0
    }
533
}
534
535
/// A string for a `Vendor::Custom` that can either be used in `const`
536
/// contexts or hold dynamic strings.
537
#[derive(Clone, Debug, Eq)]
538
pub enum CustomVendor {
539
    /// An owned `String`. This supports the general case.
540
    Owned(Box<String>),
541
    /// A static `str`, so that `CustomVendor` can be constructed in `const`
542
    /// contexts.
543
    Static(&'static str),
544
}
545
546
impl CustomVendor {
547
    /// Extracts a string slice.
548
0
    pub fn as_str(&self) -> &str {
549
0
        match self {
550
0
            CustomVendor::Owned(s) => s,
551
0
            CustomVendor::Static(s) => s,
552
        }
553
0
    }
554
}
555
556
impl PartialEq for CustomVendor {
557
0
    fn eq(&self, other: &Self) -> bool {
558
0
        self.as_str() == other.as_str()
559
0
    }
560
}
561
562
impl Hash for CustomVendor {
563
0
    fn hash<H: Hasher>(&self, state: &mut H) {
564
0
        self.as_str().hash(state)
565
0
    }
566
}
567
568
/// The "vendor" field, which in practice is little more than an arbitrary
569
/// modifier.
570
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
571
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
572
#[allow(missing_docs)]
573
pub enum Vendor {
574
    Unknown,
575
    Amd,
576
    Apple,
577
    Espressif,
578
    Experimental,
579
    Fortanix,
580
    Ibm,
581
    Kmc,
582
    Nintendo,
583
    Nvidia,
584
    Pc,
585
    Rumprun,
586
    Sun,
587
    Uwp,
588
    Wrs,
589
590
    /// A custom vendor. "Custom" in this context means that the vendor is
591
    /// not specifically recognized by upstream Autotools, LLVM, Rust, or other
592
    /// relevant authorities on triple naming. It's useful for people building
593
    /// and using locally patched toolchains.
594
    ///
595
    /// Outside of such patched environments, users of `target-lexicon` should
596
    /// treat `Custom` the same as `Unknown` and ignore the string.
597
    Custom(CustomVendor),
598
}
599
600
impl Vendor {
601
    /// Extracts a string slice.
602
171k
    pub fn as_str(&self) -> &str {
603
171k
        use Vendor::*;
604
171k
605
171k
        match self {
606
171k
            Unknown => "unknown",
607
0
            Amd => "amd",
608
0
            Apple => "apple",
609
0
            Espressif => "espressif",
610
0
            Experimental => "experimental",
611
0
            Fortanix => "fortanix",
612
0
            Ibm => "ibm",
613
0
            Kmc => "kmc",
614
0
            Nintendo => "nintendo",
615
0
            Nvidia => "nvidia",
616
0
            Pc => "pc",
617
0
            Rumprun => "rumprun",
618
0
            Sun => "sun",
619
0
            Uwp => "uwp",
620
0
            Wrs => "wrs",
621
0
            Custom(name) => name.as_str(),
622
        }
623
171k
    }
624
}
625
626
/// The "operating system" field, which sometimes implies an environment, and
627
/// sometimes isn't an actual operating system.
628
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
629
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
630
#[allow(missing_docs)]
631
pub enum OperatingSystem {
632
    Unknown,
633
    Aix,
634
    AmdHsa,
635
    Bitrig,
636
    Cloudabi,
637
    Cuda,
638
    Darwin,
639
    Dragonfly,
640
    Emscripten,
641
    Espidf,
642
    Freebsd,
643
    Fuchsia,
644
    Haiku,
645
    Hermit,
646
    Horizon,
647
    Hurd,
648
    Illumos,
649
    Ios,
650
    L4re,
651
    Linux,
652
    MacOSX { major: u16, minor: u16, patch: u16 },
653
    Nebulet,
654
    Netbsd,
655
    None_,
656
    Openbsd,
657
    Psp,
658
    Redox,
659
    Solaris,
660
    SolidAsp3,
661
    Tvos,
662
    Uefi,
663
    Visionos,
664
    VxWorks,
665
    Wasi,
666
    WasiP1,
667
    WasiP2,
668
    Watchos,
669
    Windows,
670
}
671
672
impl OperatingSystem {
673
    /// Convert into a string
674
171k
    pub fn into_str(self) -> Cow<'static, str> {
675
171k
        use OperatingSystem::*;
676
171k
677
171k
        match self {
678
0
            Unknown => Cow::Borrowed("unknown"),
679
0
            Aix => Cow::Borrowed("aix"),
680
0
            AmdHsa => Cow::Borrowed("amdhsa"),
681
0
            Bitrig => Cow::Borrowed("bitrig"),
682
0
            Cloudabi => Cow::Borrowed("cloudabi"),
683
0
            Cuda => Cow::Borrowed("cuda"),
684
0
            Darwin => Cow::Borrowed("darwin"),
685
0
            Dragonfly => Cow::Borrowed("dragonfly"),
686
0
            Emscripten => Cow::Borrowed("emscripten"),
687
0
            Espidf => Cow::Borrowed("espidf"),
688
0
            Freebsd => Cow::Borrowed("freebsd"),
689
0
            Fuchsia => Cow::Borrowed("fuchsia"),
690
0
            Haiku => Cow::Borrowed("haiku"),
691
0
            Hermit => Cow::Borrowed("hermit"),
692
0
            Horizon => Cow::Borrowed("horizon"),
693
0
            Hurd => Cow::Borrowed("hurd"),
694
0
            Illumos => Cow::Borrowed("illumos"),
695
0
            Ios => Cow::Borrowed("ios"),
696
0
            L4re => Cow::Borrowed("l4re"),
697
171k
            Linux => Cow::Borrowed("linux"),
698
            MacOSX {
699
0
                major,
700
0
                minor,
701
0
                patch,
702
0
            } => Cow::Owned(format!("macosx{}.{}.{}", major, minor, patch)),
703
0
            Nebulet => Cow::Borrowed("nebulet"),
704
0
            Netbsd => Cow::Borrowed("netbsd"),
705
0
            None_ => Cow::Borrowed("none"),
706
0
            Openbsd => Cow::Borrowed("openbsd"),
707
0
            Psp => Cow::Borrowed("psp"),
708
0
            Redox => Cow::Borrowed("redox"),
709
0
            Solaris => Cow::Borrowed("solaris"),
710
0
            SolidAsp3 => Cow::Borrowed("solid_asp3"),
711
0
            Tvos => Cow::Borrowed("tvos"),
712
0
            Uefi => Cow::Borrowed("uefi"),
713
0
            VxWorks => Cow::Borrowed("vxworks"),
714
0
            Visionos => Cow::Borrowed("visionos"),
715
0
            Wasi => Cow::Borrowed("wasi"),
716
0
            WasiP1 => Cow::Borrowed("wasip1"),
717
0
            WasiP2 => Cow::Borrowed("wasip2"),
718
0
            Watchos => Cow::Borrowed("watchos"),
719
0
            Windows => Cow::Borrowed("windows"),
720
        }
721
171k
    }
722
}
723
724
/// The "environment" field, which specifies an ABI environment on top of the
725
/// operating system. In many configurations, this field is omitted, and the
726
/// environment is implied by the operating system.
727
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
728
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
729
#[allow(missing_docs)]
730
pub enum Environment {
731
    Unknown,
732
    AmdGiz,
733
    Android,
734
    Androideabi,
735
    Eabi,
736
    Eabihf,
737
    Gnu,
738
    Gnuabi64,
739
    Gnueabi,
740
    Gnueabihf,
741
    Gnuspe,
742
    Gnux32,
743
    GnuIlp32,
744
    GnuLlvm,
745
    HermitKernel,
746
    HurdKernel,
747
    LinuxKernel,
748
    Macabi,
749
    Musl,
750
    Musleabi,
751
    Musleabihf,
752
    Muslabi64,
753
    Msvc,
754
    Newlib,
755
    None,
756
    Kernel,
757
    Uclibc,
758
    Uclibceabi,
759
    Uclibceabihf,
760
    Sgx,
761
    Sim,
762
    Softfloat,
763
    Spe,
764
    Threads,
765
    Ohos,
766
}
767
768
impl Environment {
769
    /// Convert into a string
770
171k
    pub fn into_str(self) -> Cow<'static, str> {
771
171k
        use Environment::*;
772
171k
773
171k
        match self {
774
0
            Unknown => Cow::Borrowed("unknown"),
775
0
            AmdGiz => Cow::Borrowed("amdgiz"),
776
0
            Android => Cow::Borrowed("android"),
777
0
            Androideabi => Cow::Borrowed("androideabi"),
778
0
            Eabi => Cow::Borrowed("eabi"),
779
0
            Eabihf => Cow::Borrowed("eabihf"),
780
171k
            Gnu => Cow::Borrowed("gnu"),
781
0
            Gnuabi64 => Cow::Borrowed("gnuabi64"),
782
0
            Gnueabi => Cow::Borrowed("gnueabi"),
783
0
            Gnueabihf => Cow::Borrowed("gnueabihf"),
784
0
            Gnuspe => Cow::Borrowed("gnuspe"),
785
0
            Gnux32 => Cow::Borrowed("gnux32"),
786
0
            GnuIlp32 => Cow::Borrowed("gnu_ilp32"),
787
0
            GnuLlvm => Cow::Borrowed("gnullvm"),
788
0
            HermitKernel => Cow::Borrowed("hermitkernel"),
789
0
            HurdKernel => Cow::Borrowed("hurdkernel"),
790
0
            LinuxKernel => Cow::Borrowed("linuxkernel"),
791
0
            Macabi => Cow::Borrowed("macabi"),
792
0
            Musl => Cow::Borrowed("musl"),
793
0
            Musleabi => Cow::Borrowed("musleabi"),
794
0
            Musleabihf => Cow::Borrowed("musleabihf"),
795
0
            Muslabi64 => Cow::Borrowed("muslabi64"),
796
0
            Msvc => Cow::Borrowed("msvc"),
797
0
            Newlib => Cow::Borrowed("newlib"),
798
0
            None => Cow::Borrowed("none"),
799
0
            Kernel => Cow::Borrowed("kernel"),
800
0
            Uclibc => Cow::Borrowed("uclibc"),
801
0
            Uclibceabi => Cow::Borrowed("uclibceabi"),
802
0
            Uclibceabihf => Cow::Borrowed("uclibceabihf"),
803
0
            Sgx => Cow::Borrowed("sgx"),
804
0
            Sim => Cow::Borrowed("sim"),
805
0
            Softfloat => Cow::Borrowed("softfloat"),
806
0
            Spe => Cow::Borrowed("spe"),
807
0
            Threads => Cow::Borrowed("threads"),
808
0
            Ohos => Cow::Borrowed("ohos"),
809
        }
810
171k
    }
811
}
812
813
/// The "binary format" field, which is usually omitted, and the binary format
814
/// is implied by the other fields.
815
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
816
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
817
#[allow(missing_docs)]
818
pub enum BinaryFormat {
819
    Unknown,
820
    Elf,
821
    Coff,
822
    Macho,
823
    Wasm,
824
    Xcoff,
825
}
826
827
impl BinaryFormat {
828
    /// Convert into a string
829
0
    pub fn into_str(self) -> Cow<'static, str> {
830
0
        use BinaryFormat::*;
831
0
832
0
        match self {
833
0
            Unknown => Cow::Borrowed("unknown"),
834
0
            Elf => Cow::Borrowed("elf"),
835
0
            Coff => Cow::Borrowed("coff"),
836
0
            Macho => Cow::Borrowed("macho"),
837
0
            Wasm => Cow::Borrowed("wasm"),
838
0
            Xcoff => Cow::Borrowed("xcoff"),
839
        }
840
0
    }
841
}
842
843
impl Architecture {
844
    /// Return the endianness of this architecture.
845
    #[rustfmt::skip]
846
28.4k
    pub fn endianness(self) -> Result<Endianness, ()> {
847
        use Architecture::*;
848
849
0
        match self {
850
0
            Unknown => Err(()),
851
0
            Arm(arm) => Ok(arm.endianness()),
852
0
            Aarch64(aarch) => Ok(aarch.endianness()),
853
            AmdGcn
854
            | Asmjs
855
            | Avr
856
            | Bpfel
857
            | Hexagon
858
            | X86_32(_)
859
            | LoongArch64
860
            | Mips64(Mips64Architecture::Mips64el)
861
            | Mips32(Mips32Architecture::Mipsel)
862
            | Mips32(Mips32Architecture::Mipsisa32r6el)
863
            | Mips64(Mips64Architecture::Mipsisa64r6el)
864
            | Msp430
865
            | Nvptx64
866
            | Powerpc64le
867
            | Riscv32(_)
868
            | Riscv64(_)
869
            | Wasm32
870
            | Wasm64
871
            | X86_64
872
            | X86_64h
873
            | XTensa
874
28.4k
            | Clever(_) => Ok(Endianness::Little),
875
            Bpfeb
876
            | M68k
877
            | Mips32(Mips32Architecture::Mips)
878
            | Mips64(Mips64Architecture::Mips64)
879
            | Mips32(Mips32Architecture::Mipsisa32r6)
880
            | Mips64(Mips64Architecture::Mipsisa64r6)
881
            | Powerpc
882
            | Powerpc64
883
            | S390x
884
            | Sparc
885
            | Sparc64
886
0
            | Sparcv9 => Ok(Endianness::Big),
887
            #[cfg(feature="arch_zkasm")]
888
            ZkAsm => Ok(Endianness::Big),
889
        }
890
891
28.4k
    }
892
893
    /// Return the pointer bit width of this target's architecture.
894
    ///
895
    /// This function is only aware of the CPU architecture so it is not aware
896
    /// of ilp32 and x32 ABIs.
897
    #[rustfmt::skip]
898
914k
    pub fn pointer_width(self) -> Result<PointerWidth, ()> {
899
914k
        use Architecture::*;
900
914k
901
914k
        match self {
902
0
            Unknown => Err(()),
903
0
            Avr | Msp430 => Ok(PointerWidth::U16),
904
0
            Arm(arm) => Ok(arm.pointer_width()),
905
0
            Aarch64(aarch) => Ok(aarch.pointer_width()),
906
            Asmjs
907
            | Hexagon
908
            | X86_32(_)
909
            | Riscv32(_)
910
            | Sparc
911
            | Wasm32
912
            | M68k
913
            | Mips32(_)
914
            | Powerpc
915
0
            | XTensa => Ok(PointerWidth::U32),
916
            AmdGcn
917
            | Bpfeb
918
            | Bpfel
919
            | Powerpc64le
920
            | Riscv64(_)
921
            | X86_64
922
            | X86_64h
923
            | Mips64(_)
924
            | Nvptx64
925
            | Powerpc64
926
            | S390x
927
            | Sparc64
928
            | Sparcv9
929
            | LoongArch64
930
            | Wasm64
931
914k
            | Clever(_) => Ok(PointerWidth::U64),
932
            #[cfg(feature="arch_zkasm")]
933
            ZkAsm => Ok(PointerWidth::U64),
934
        }
935
914k
    }
936
937
    /// Checks if this Architecture is some variant of Clever-ISA
938
171k
    pub fn is_clever(&self) -> bool {
939
171k
        match self {
940
0
            Architecture::Clever(_) => true,
941
171k
            _ => false,
942
        }
943
171k
    }
944
945
    /// Convert into a string
946
171k
    pub fn into_str(self) -> Cow<'static, str> {
947
171k
        use Architecture::*;
948
171k
949
171k
        match self {
950
0
            Arm(arm) => arm.into_str(),
951
0
            Aarch64(aarch) => aarch.into_str(),
952
0
            Unknown => Cow::Borrowed("unknown"),
953
0
            AmdGcn => Cow::Borrowed("amdgcn"),
954
0
            Asmjs => Cow::Borrowed("asmjs"),
955
0
            Avr => Cow::Borrowed("avr"),
956
0
            Bpfeb => Cow::Borrowed("bpfeb"),
957
0
            Bpfel => Cow::Borrowed("bpfel"),
958
0
            Hexagon => Cow::Borrowed("hexagon"),
959
0
            X86_32(x86_32) => x86_32.into_str(),
960
0
            LoongArch64 => Cow::Borrowed("loongarch64"),
961
0
            M68k => Cow::Borrowed("m68k"),
962
0
            Mips32(mips32) => mips32.into_str(),
963
0
            Mips64(mips64) => mips64.into_str(),
964
0
            Msp430 => Cow::Borrowed("msp430"),
965
0
            Nvptx64 => Cow::Borrowed("nvptx64"),
966
0
            Powerpc => Cow::Borrowed("powerpc"),
967
0
            Powerpc64 => Cow::Borrowed("powerpc64"),
968
0
            Powerpc64le => Cow::Borrowed("powerpc64le"),
969
0
            Riscv32(riscv32) => riscv32.into_str(),
970
0
            Riscv64(riscv64) => riscv64.into_str(),
971
0
            S390x => Cow::Borrowed("s390x"),
972
0
            Sparc => Cow::Borrowed("sparc"),
973
0
            Sparc64 => Cow::Borrowed("sparc64"),
974
0
            Sparcv9 => Cow::Borrowed("sparcv9"),
975
0
            Wasm32 => Cow::Borrowed("wasm32"),
976
0
            Wasm64 => Cow::Borrowed("wasm64"),
977
171k
            X86_64 => Cow::Borrowed("x86_64"),
978
0
            X86_64h => Cow::Borrowed("x86_64h"),
979
0
            XTensa => Cow::Borrowed("xtensa"),
980
0
            Clever(ver) => ver.into_str(),
981
            #[cfg(feature = "arch_zkasm")]
982
            ZkAsm => Cow::Borrowed("zkasm"),
983
        }
984
171k
    }
985
}
986
987
/// Return the binary format implied by this target triple, ignoring its
988
/// `binary_format` field.
989
171k
pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat {
990
171k
    match triple.operating_system {
991
0
        OperatingSystem::None_ => match triple.environment {
992
0
            Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf,
993
0
            _ => BinaryFormat::Unknown,
994
        },
995
0
        OperatingSystem::Aix => BinaryFormat::Xcoff,
996
        OperatingSystem::Darwin
997
        | OperatingSystem::Ios
998
        | OperatingSystem::MacOSX { .. }
999
        | OperatingSystem::Visionos
1000
        | OperatingSystem::Watchos
1001
0
        | OperatingSystem::Tvos => BinaryFormat::Macho,
1002
0
        OperatingSystem::Windows => BinaryFormat::Coff,
1003
        OperatingSystem::Nebulet
1004
        | OperatingSystem::Emscripten
1005
        | OperatingSystem::VxWorks
1006
        | OperatingSystem::Wasi
1007
0
        | OperatingSystem::Unknown => match triple.architecture {
1008
0
            Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm,
1009
0
            Architecture::Unknown => BinaryFormat::Unknown,
1010
            // Default to ELF, following `getDefaultFormat` in LLVM.
1011
0
            _ => BinaryFormat::Elf,
1012
        },
1013
171k
        _ => BinaryFormat::Elf,
1014
    }
1015
171k
}
1016
1017
impl fmt::Display for ArmArchitecture {
1018
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1019
0
        f.write_str(&self.into_str())
1020
0
    }
1021
}
1022
1023
impl fmt::Display for Aarch64Architecture {
1024
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1025
0
        f.write_str(&self.into_str())
1026
0
    }
1027
}
1028
1029
impl fmt::Display for CleverArchitecture {
1030
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1031
0
        f.write_str(&self.into_str())
1032
0
    }
1033
}
1034
1035
impl fmt::Display for Riscv32Architecture {
1036
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1037
0
        f.write_str(&self.into_str())
1038
0
    }
1039
}
1040
1041
impl fmt::Display for Riscv64Architecture {
1042
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1043
0
        f.write_str(&self.into_str())
1044
0
    }
1045
}
1046
1047
impl fmt::Display for X86_32Architecture {
1048
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1049
0
        f.write_str(&self.into_str())
1050
0
    }
1051
}
1052
1053
impl fmt::Display for Mips32Architecture {
1054
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1055
0
        f.write_str(&self.into_str())
1056
0
    }
1057
}
1058
1059
impl fmt::Display for Mips64Architecture {
1060
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1061
0
        f.write_str(&self.into_str())
1062
0
    }
1063
}
1064
1065
impl fmt::Display for Architecture {
1066
171k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1067
171k
        f.write_str(&self.into_str())
1068
171k
    }
1069
}
1070
1071
impl FromStr for ArmArchitecture {
1072
    type Err = ();
1073
1074
0
    fn from_str(s: &str) -> Result<Self, ()> {
1075
0
        use ArmArchitecture::*;
1076
0
1077
0
        Ok(match s {
1078
0
            "arm" => Arm,
1079
0
            "armeb" => Armeb,
1080
0
            "armv4" => Armv4,
1081
0
            "armv4t" => Armv4t,
1082
0
            "armv5t" => Armv5t,
1083
0
            "armv5te" => Armv5te,
1084
0
            "armv5tej" => Armv5tej,
1085
0
            "armv6" => Armv6,
1086
0
            "armv6j" => Armv6j,
1087
0
            "armv6k" => Armv6k,
1088
0
            "armv6z" => Armv6z,
1089
0
            "armv6kz" => Armv6kz,
1090
0
            "armv6t2" => Armv6t2,
1091
0
            "armv6m" => Armv6m,
1092
0
            "armv7" => Armv7,
1093
0
            "armv7a" => Armv7a,
1094
0
            "armv7k" => Armv7k,
1095
0
            "armv7ve" => Armv7ve,
1096
0
            "armv7m" => Armv7m,
1097
0
            "armv7r" => Armv7r,
1098
0
            "armv7s" => Armv7s,
1099
0
            "armv8" => Armv8,
1100
0
            "armv8a" => Armv8a,
1101
0
            "armv8.1a" => Armv8_1a,
1102
0
            "armv8.2a" => Armv8_2a,
1103
0
            "armv8.3a" => Armv8_3a,
1104
0
            "armv8.4a" => Armv8_4a,
1105
0
            "armv8.5a" => Armv8_5a,
1106
0
            "armv8m.base" => Armv8mBase,
1107
0
            "armv8m.main" => Armv8mMain,
1108
0
            "armv8r" => Armv8r,
1109
0
            "thumbeb" => Thumbeb,
1110
0
            "thumbv4t" => Thumbv4t,
1111
0
            "thumbv5te" => Thumbv5te,
1112
0
            "thumbv6m" => Thumbv6m,
1113
0
            "thumbv7a" => Thumbv7a,
1114
0
            "thumbv7em" => Thumbv7em,
1115
0
            "thumbv7m" => Thumbv7m,
1116
0
            "thumbv7neon" => Thumbv7neon,
1117
0
            "thumbv8m.base" => Thumbv8mBase,
1118
0
            "thumbv8m.main" => Thumbv8mMain,
1119
0
            "armebv7r" => Armebv7r,
1120
0
            _ => return Err(()),
1121
        })
1122
0
    }
1123
}
1124
1125
impl FromStr for Aarch64Architecture {
1126
    type Err = ();
1127
1128
0
    fn from_str(s: &str) -> Result<Self, ()> {
1129
0
        use Aarch64Architecture::*;
1130
0
1131
0
        Ok(match s {
1132
0
            "aarch64" => Aarch64,
1133
0
            "arm64" => Aarch64,
1134
0
            "aarch64_be" => Aarch64be,
1135
0
            _ => return Err(()),
1136
        })
1137
0
    }
1138
}
1139
1140
impl FromStr for CleverArchitecture {
1141
    type Err = ();
1142
0
    fn from_str(s: &str) -> Result<Self, ()> {
1143
0
        match s {
1144
0
            "clever" => Ok(CleverArchitecture::Clever),
1145
0
            "clever1.0" => Ok(CleverArchitecture::Clever1_0),
1146
0
            _ => Err(()),
1147
        }
1148
0
    }
1149
}
1150
1151
impl FromStr for Riscv32Architecture {
1152
    type Err = ();
1153
1154
0
    fn from_str(s: &str) -> Result<Self, ()> {
1155
0
        use Riscv32Architecture::*;
1156
0
1157
0
        Ok(match s {
1158
0
            "riscv32" => Riscv32,
1159
0
            "riscv32gc" => Riscv32gc,
1160
0
            "riscv32i" => Riscv32i,
1161
0
            "riscv32im" => Riscv32im,
1162
0
            "riscv32ima" => Riscv32ima,
1163
0
            "riscv32imac" => Riscv32imac,
1164
0
            "riscv32imafc" => Riscv32imafc,
1165
0
            "riscv32imc" => Riscv32imc,
1166
0
            _ => return Err(()),
1167
        })
1168
0
    }
1169
}
1170
1171
impl FromStr for Riscv64Architecture {
1172
    type Err = ();
1173
1174
0
    fn from_str(s: &str) -> Result<Self, ()> {
1175
0
        use Riscv64Architecture::*;
1176
0
1177
0
        Ok(match s {
1178
0
            "riscv64" => Riscv64,
1179
0
            "riscv64gc" => Riscv64gc,
1180
0
            "riscv64imac" => Riscv64imac,
1181
0
            _ => return Err(()),
1182
        })
1183
0
    }
1184
}
1185
1186
impl FromStr for X86_32Architecture {
1187
    type Err = ();
1188
1189
0
    fn from_str(s: &str) -> Result<Self, ()> {
1190
0
        use X86_32Architecture::*;
1191
0
1192
0
        Ok(match s {
1193
0
            "i386" => I386,
1194
0
            "i586" => I586,
1195
0
            "i686" => I686,
1196
0
            _ => return Err(()),
1197
        })
1198
0
    }
1199
}
1200
1201
impl FromStr for Mips32Architecture {
1202
    type Err = ();
1203
1204
0
    fn from_str(s: &str) -> Result<Self, ()> {
1205
0
        use Mips32Architecture::*;
1206
0
1207
0
        Ok(match s {
1208
0
            "mips" => Mips,
1209
0
            "mipsel" => Mipsel,
1210
0
            "mipsisa32r6" => Mipsisa32r6,
1211
0
            "mipsisa32r6el" => Mipsisa32r6el,
1212
0
            _ => return Err(()),
1213
        })
1214
0
    }
1215
}
1216
1217
impl FromStr for Mips64Architecture {
1218
    type Err = ();
1219
1220
0
    fn from_str(s: &str) -> Result<Self, ()> {
1221
0
        use Mips64Architecture::*;
1222
0
1223
0
        Ok(match s {
1224
0
            "mips64" => Mips64,
1225
0
            "mips64el" => Mips64el,
1226
0
            "mipsisa64r6" => Mipsisa64r6,
1227
0
            "mipsisa64r6el" => Mipsisa64r6el,
1228
0
            _ => return Err(()),
1229
        })
1230
0
    }
1231
}
1232
1233
impl FromStr for Architecture {
1234
    type Err = ();
1235
1236
0
    fn from_str(s: &str) -> Result<Self, ()> {
1237
0
        use Architecture::*;
1238
0
1239
0
        Ok(match s {
1240
0
            "unknown" => Unknown,
1241
0
            "amdgcn" => AmdGcn,
1242
0
            "asmjs" => Asmjs,
1243
0
            "avr" => Avr,
1244
0
            "bpfeb" => Bpfeb,
1245
0
            "bpfel" => Bpfel,
1246
0
            "hexagon" => Hexagon,
1247
0
            "loongarch64" => LoongArch64,
1248
0
            "m68k" => M68k,
1249
0
            "msp430" => Msp430,
1250
0
            "nvptx64" => Nvptx64,
1251
0
            "powerpc" => Powerpc,
1252
0
            "powerpc64" => Powerpc64,
1253
0
            "powerpc64le" => Powerpc64le,
1254
0
            "s390x" => S390x,
1255
0
            "sparc" => Sparc,
1256
0
            "sparc64" => Sparc64,
1257
0
            "sparcv9" => Sparcv9,
1258
0
            "wasm32" => Wasm32,
1259
0
            "wasm64" => Wasm64,
1260
0
            "x86_64" => X86_64,
1261
0
            "x86_64h" => X86_64h,
1262
0
            "xtensa" => XTensa,
1263
            #[cfg(feature = "arch_zkasm")]
1264
            "zkasm" => ZkAsm,
1265
            _ => {
1266
0
                if let Ok(arm) = ArmArchitecture::from_str(s) {
1267
0
                    Arm(arm)
1268
0
                } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) {
1269
0
                    Aarch64(aarch64)
1270
0
                } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) {
1271
0
                    Riscv32(riscv32)
1272
0
                } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) {
1273
0
                    Riscv64(riscv64)
1274
0
                } else if let Ok(x86_32) = X86_32Architecture::from_str(s) {
1275
0
                    X86_32(x86_32)
1276
0
                } else if let Ok(mips32) = Mips32Architecture::from_str(s) {
1277
0
                    Mips32(mips32)
1278
0
                } else if let Ok(mips64) = Mips64Architecture::from_str(s) {
1279
0
                    Mips64(mips64)
1280
0
                } else if let Ok(clever) = CleverArchitecture::from_str(s) {
1281
0
                    Clever(clever)
1282
                } else {
1283
0
                    return Err(());
1284
                }
1285
            }
1286
        })
1287
0
    }
1288
}
1289
1290
impl fmt::Display for Vendor {
1291
171k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1292
171k
        f.write_str(self.as_str())
1293
171k
    }
1294
}
1295
1296
impl FromStr for Vendor {
1297
    type Err = ();
1298
1299
0
    fn from_str(s: &str) -> Result<Self, ()> {
1300
0
        use Vendor::*;
1301
0
1302
0
        Ok(match s {
1303
0
            "unknown" => Unknown,
1304
0
            "amd" => Amd,
1305
0
            "apple" => Apple,
1306
0
            "espressif" => Espressif,
1307
0
            "experimental" => Experimental,
1308
0
            "fortanix" => Fortanix,
1309
0
            "ibm" => Ibm,
1310
0
            "kmc" => Kmc,
1311
0
            "nintendo" => Nintendo,
1312
0
            "nvidia" => Nvidia,
1313
0
            "pc" => Pc,
1314
0
            "rumprun" => Rumprun,
1315
0
            "sun" => Sun,
1316
0
            "uwp" => Uwp,
1317
0
            "wrs" => Wrs,
1318
0
            custom => {
1319
0
                #[cfg(not(feature = "std"))]
1320
0
                use alloc::borrow::ToOwned;
1321
0
1322
0
                // A custom vendor. Since triple syntax is so loosely defined,
1323
0
                // be as conservative as we can to avoid potential ambiguities.
1324
0
                // We err on the side of being too strict here, as we can
1325
0
                // always relax it if needed.
1326
0
1327
0
                // Don't allow empty string names.
1328
0
                if custom.is_empty() {
1329
0
                    return Err(());
1330
0
                }
1331
0
1332
0
                // Don't allow any other recognized name as a custom vendor,
1333
0
                // since vendors can be omitted in some contexts.
1334
0
                if Architecture::from_str(custom).is_ok()
1335
0
                    || OperatingSystem::from_str(custom).is_ok()
1336
0
                    || Environment::from_str(custom).is_ok()
1337
0
                    || BinaryFormat::from_str(custom).is_ok()
1338
                {
1339
0
                    return Err(());
1340
0
                }
1341
0
1342
0
                // Require the first character to be an ascii lowercase.
1343
0
                if !custom.chars().next().unwrap().is_ascii_lowercase() {
1344
0
                    return Err(());
1345
0
                }
1346
0
1347
0
                // Restrict the set of characters permitted in a custom vendor.
1348
0
                let has_restricted = custom.chars().any(|c: char| {
1349
0
                    !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.')
1350
0
                });
1351
0
1352
0
                if has_restricted {
1353
0
                    return Err(());
1354
0
                }
1355
0
1356
0
                Custom(CustomVendor::Owned(Box::new(custom.to_owned())))
1357
            }
1358
        })
1359
0
    }
1360
}
1361
1362
impl fmt::Display for OperatingSystem {
1363
171k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1364
171k
        use OperatingSystem::*;
1365
171k
1366
171k
        match *self {
1367
            MacOSX {
1368
0
                major,
1369
0
                minor,
1370
0
                patch,
1371
0
            } => write!(f, "macosx{}.{}.{}", major, minor, patch),
1372
171k
            os => f.write_str(&os.into_str()),
1373
        }
1374
171k
    }
1375
}
1376
1377
impl FromStr for OperatingSystem {
1378
    type Err = ();
1379
1380
0
    fn from_str(s: &str) -> Result<Self, ()> {
1381
0
        use OperatingSystem::*;
1382
0
1383
0
        // TODO also parse version number for darwin and ios OSes
1384
0
        if s.starts_with("macosx") {
1385
            // Parse operating system names like `macosx10.7.0`.
1386
0
            let s = &s["macosx".len()..];
1387
0
            let mut parts = s.split('.').map(|num| num.parse::<u16>());
1388
1389
            macro_rules! get_part {
1390
                () => {
1391
                    if let Some(Ok(part)) = parts.next() {
1392
                        part
1393
                    } else {
1394
                        return Err(());
1395
                    }
1396
                };
1397
            }
1398
1399
0
            let major = get_part!();
1400
0
            let minor = get_part!();
1401
0
            let patch = get_part!();
1402
1403
0
            if parts.next().is_some() {
1404
0
                return Err(());
1405
0
            }
1406
0
1407
0
            return Ok(MacOSX {
1408
0
                major,
1409
0
                minor,
1410
0
                patch,
1411
0
            });
1412
0
        }
1413
0
1414
0
        Ok(match s {
1415
0
            "unknown" => Unknown,
1416
0
            "aix" => Aix,
1417
0
            "amdhsa" => AmdHsa,
1418
0
            "bitrig" => Bitrig,
1419
0
            "cloudabi" => Cloudabi,
1420
0
            "cuda" => Cuda,
1421
0
            "darwin" => Darwin,
1422
0
            "dragonfly" => Dragonfly,
1423
0
            "emscripten" => Emscripten,
1424
0
            "freebsd" => Freebsd,
1425
0
            "fuchsia" => Fuchsia,
1426
0
            "haiku" => Haiku,
1427
0
            "hermit" => Hermit,
1428
0
            "horizon" => Horizon,
1429
0
            "hurd" => Hurd,
1430
0
            "illumos" => Illumos,
1431
0
            "ios" => Ios,
1432
0
            "l4re" => L4re,
1433
0
            "linux" => Linux,
1434
0
            "nebulet" => Nebulet,
1435
0
            "netbsd" => Netbsd,
1436
0
            "none" => None_,
1437
0
            "openbsd" => Openbsd,
1438
0
            "psp" => Psp,
1439
0
            "redox" => Redox,
1440
0
            "solaris" => Solaris,
1441
0
            "solid_asp3" => SolidAsp3,
1442
0
            "tvos" => Tvos,
1443
0
            "uefi" => Uefi,
1444
0
            "visionos" => Visionos,
1445
0
            "vxworks" => VxWorks,
1446
0
            "wasi" => Wasi,
1447
0
            "wasip1" => WasiP1,
1448
0
            "wasip2" => WasiP2,
1449
0
            "watchos" => Watchos,
1450
0
            "windows" => Windows,
1451
0
            "espidf" => Espidf,
1452
0
            _ => return Err(()),
1453
        })
1454
0
    }
1455
}
1456
1457
impl fmt::Display for Environment {
1458
171k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1459
171k
        f.write_str(&self.into_str())
1460
171k
    }
1461
}
1462
1463
impl FromStr for Environment {
1464
    type Err = ();
1465
1466
0
    fn from_str(s: &str) -> Result<Self, ()> {
1467
0
        use Environment::*;
1468
0
1469
0
        Ok(match s {
1470
0
            "unknown" => Unknown,
1471
0
            "amdgiz" => AmdGiz,
1472
0
            "android" => Android,
1473
0
            "androideabi" => Androideabi,
1474
0
            "eabi" => Eabi,
1475
0
            "eabihf" => Eabihf,
1476
0
            "gnu" => Gnu,
1477
0
            "gnuabi64" => Gnuabi64,
1478
0
            "gnueabi" => Gnueabi,
1479
0
            "gnueabihf" => Gnueabihf,
1480
0
            "gnuspe" => Gnuspe,
1481
0
            "gnux32" => Gnux32,
1482
0
            "gnu_ilp32" => GnuIlp32,
1483
0
            "gnullvm" => GnuLlvm,
1484
0
            "hermitkernel" => HermitKernel,
1485
0
            "hurdkernel" => HurdKernel,
1486
0
            "linuxkernel" => LinuxKernel,
1487
0
            "macabi" => Macabi,
1488
0
            "musl" => Musl,
1489
0
            "musleabi" => Musleabi,
1490
0
            "musleabihf" => Musleabihf,
1491
0
            "muslabi64" => Muslabi64,
1492
0
            "msvc" => Msvc,
1493
0
            "newlib" => Newlib,
1494
0
            "none" => None,
1495
0
            "kernel" => Kernel,
1496
0
            "uclibc" => Uclibc,
1497
0
            "uclibceabi" => Uclibceabi,
1498
0
            "uclibceabihf" => Uclibceabihf,
1499
0
            "sgx" => Sgx,
1500
0
            "sim" => Sim,
1501
0
            "softfloat" => Softfloat,
1502
0
            "spe" => Spe,
1503
0
            "threads" => Threads,
1504
0
            "ohos" => Ohos,
1505
0
            _ => return Err(()),
1506
        })
1507
0
    }
1508
}
1509
1510
impl fmt::Display for BinaryFormat {
1511
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1512
0
        f.write_str(&self.into_str())
1513
0
    }
1514
}
1515
1516
impl FromStr for BinaryFormat {
1517
    type Err = ();
1518
1519
0
    fn from_str(s: &str) -> Result<Self, ()> {
1520
0
        use BinaryFormat::*;
1521
0
1522
0
        Ok(match s {
1523
0
            "unknown" => Unknown,
1524
0
            "elf" => Elf,
1525
0
            "coff" => Coff,
1526
0
            "macho" => Macho,
1527
0
            "wasm" => Wasm,
1528
0
            "xcoff" => Xcoff,
1529
0
            _ => return Err(()),
1530
        })
1531
0
    }
1532
}
1533
1534
#[cfg(test)]
1535
mod tests {
1536
    use super::*;
1537
    use alloc::string::ToString;
1538
1539
    #[test]
1540
    fn roundtrip_known_triples() {
1541
        // This list is constructed from:
1542
        //  - targets emitted by "rustup target list"
1543
        //  - targets emitted by "rustc +nightly --print target-list"
1544
        //  - targets contributors have added
1545
        let targets = [
1546
            "aarch64-apple-darwin",
1547
            "aarch64-apple-ios",
1548
            "aarch64-apple-ios-macabi",
1549
            "aarch64-apple-ios-sim",
1550
            "aarch64-apple-tvos",
1551
            "aarch64-apple-tvos-sim",
1552
            "aarch64-apple-visionos",
1553
            "aarch64-apple-visionos-sim",
1554
            "aarch64-apple-watchos",
1555
            "aarch64-apple-watchos-sim",
1556
            "aarch64_be-unknown-linux-gnu",
1557
            "aarch64_be-unknown-linux-gnu_ilp32",
1558
            "aarch64_be-unknown-netbsd",
1559
            "aarch64-kmc-solid_asp3",
1560
            "aarch64-linux-android",
1561
            //"aarch64-nintendo-switch-freestanding", // TODO
1562
            "aarch64-pc-windows-gnullvm",
1563
            "aarch64-pc-windows-msvc",
1564
            "aarch64-unknown-cloudabi",
1565
            "aarch64-unknown-freebsd",
1566
            "aarch64-unknown-fuchsia",
1567
            "aarch64-unknown-hermit",
1568
            "aarch64-unknown-illumos",
1569
            "aarch64-unknown-linux-gnu",
1570
            "aarch64-unknown-linux-gnu_ilp32",
1571
            "aarch64-unknown-linux-musl",
1572
            "aarch64-unknown-linux-ohos",
1573
            "aarch64-unknown-netbsd",
1574
            "aarch64-unknown-none",
1575
            "aarch64-unknown-none-softfloat",
1576
            //"aarch64-unknown-nto-qnx710", // TODO
1577
            "aarch64-unknown-openbsd",
1578
            "aarch64-unknown-redox",
1579
            //"aarch64-unknown-teeos", // TODO
1580
            "aarch64-unknown-uefi",
1581
            "aarch64-uwp-windows-msvc",
1582
            "aarch64-wrs-vxworks",
1583
            //"arm64_32-apple-watchos", // TODO
1584
            //"arm64e-apple-darwin", // TODO
1585
            "amdgcn-amd-amdhsa",
1586
            "amdgcn-amd-amdhsa-amdgiz",
1587
            //"arm64e-apple-ios", // TODO
1588
            //"arm64ec-pc-windows-msvc", // TODO
1589
            "armeb-unknown-linux-gnueabi",
1590
            "armebv7r-none-eabi",
1591
            "armebv7r-none-eabihf",
1592
            "arm-linux-androideabi",
1593
            "arm-unknown-linux-gnueabi",
1594
            "arm-unknown-linux-gnueabihf",
1595
            "arm-unknown-linux-musleabi",
1596
            "arm-unknown-linux-musleabihf",
1597
            "armv4t-none-eabi",
1598
            "armv4t-unknown-linux-gnueabi",
1599
            "armv5te-none-eabi",
1600
            "armv5te-unknown-linux-gnueabi",
1601
            "armv5te-unknown-linux-musleabi",
1602
            "armv5te-unknown-linux-uclibceabi",
1603
            "armv6k-nintendo-3ds",
1604
            "armv6-unknown-freebsd",
1605
            "armv6-unknown-netbsd-eabihf",
1606
            "armv7a-kmc-solid_asp3-eabi",
1607
            "armv7a-kmc-solid_asp3-eabihf",
1608
            "armv7a-none-eabi",
1609
            "armv7a-none-eabihf",
1610
            "armv7-apple-ios",
1611
            "armv7k-apple-watchos",
1612
            "armv7-linux-androideabi",
1613
            "armv7r-none-eabi",
1614
            "armv7r-none-eabihf",
1615
            "armv7s-apple-ios",
1616
            "armv7-unknown-cloudabi-eabihf",
1617
            //"armv7-sony-vita-newlibeabihf", // TODO
1618
            "armv7-unknown-freebsd",
1619
            "armv7-unknown-linux-gnueabi",
1620
            "armv7-unknown-linux-gnueabihf",
1621
            "armv7-unknown-linux-musleabi",
1622
            "armv7-unknown-linux-musleabihf",
1623
            "armv7-unknown-linux-ohos",
1624
            "armv7-unknown-linux-uclibceabi",
1625
            "armv7-unknown-linux-uclibceabihf",
1626
            "armv7-unknown-netbsd-eabihf",
1627
            "armv7-wrs-vxworks-eabihf",
1628
            "asmjs-unknown-emscripten",
1629
            "armv8r-none-eabihf",
1630
            //"avr-unknown-gnu-atmega328", // TODO
1631
            "avr-unknown-unknown",
1632
            "bpfeb-unknown-none",
1633
            "bpfel-unknown-none",
1634
            //"csky-unknown-linux-gnuabiv2", // TODO
1635
            //"csky-unknown-linux-gnuabiv2hf", // TODO
1636
            "hexagon-unknown-linux-musl",
1637
            "hexagon-unknown-none-elf",
1638
            "i386-apple-ios",
1639
            //"i586-pc-nto-qnx700", // TODO
1640
            "i586-pc-windows-msvc",
1641
            "i586-unknown-linux-gnu",
1642
            "i586-unknown-linux-musl",
1643
            "i586-unknown-netbsd",
1644
            "i686-apple-darwin",
1645
            "i686-linux-android",
1646
            "i686-apple-macosx10.7.0",
1647
            "i686-pc-windows-gnu",
1648
            "i686-pc-windows-gnullvm",
1649
            "i686-pc-windows-msvc",
1650
            "i686-unknown-cloudabi",
1651
            "i686-unknown-dragonfly",
1652
            "i686-unknown-freebsd",
1653
            "i686-unknown-haiku",
1654
            "i686-unknown-hurd-gnu",
1655
            "i686-unknown-linux-gnu",
1656
            "i686-unknown-linux-musl",
1657
            "i686-unknown-netbsd",
1658
            "i686-unknown-openbsd",
1659
            "i686-unknown-redox",
1660
            "i686-unknown-uefi",
1661
            "i686-uwp-windows-gnu",
1662
            "i686-uwp-windows-msvc",
1663
            "i686-win7-windows-msvc",
1664
            "i686-wrs-vxworks",
1665
            "loongarch64-unknown-linux-gnu",
1666
            "loongarch64-unknown-linux-musl",
1667
            "loongarch64-unknown-none",
1668
            "loongarch64-unknown-none-softfloat",
1669
            "m68k-unknown-linux-gnu",
1670
            "mips64el-unknown-linux-gnuabi64",
1671
            "mips64el-unknown-linux-muslabi64",
1672
            "mips64-openwrt-linux-musl",
1673
            "mips64-unknown-linux-gnuabi64",
1674
            "mips64-unknown-linux-muslabi64",
1675
            "mipsel-sony-psp",
1676
            //"mipsel-sony-psx", // TODO
1677
            "mipsel-unknown-linux-gnu",
1678
            "mipsel-unknown-linux-musl",
1679
            "mipsel-unknown-linux-uclibc",
1680
            "mipsel-unknown-netbsd",
1681
            "mipsel-unknown-none",
1682
            "mipsisa32r6el-unknown-linux-gnu",
1683
            "mipsisa32r6-unknown-linux-gnu",
1684
            "mipsisa64r6el-unknown-linux-gnuabi64",
1685
            "mipsisa64r6-unknown-linux-gnuabi64",
1686
            "mips-unknown-linux-gnu",
1687
            "mips-unknown-linux-musl",
1688
            "mips-unknown-linux-uclibc",
1689
            "msp430-none-elf",
1690
            "nvptx64-nvidia-cuda",
1691
            "powerpc64-ibm-aix",
1692
            "powerpc64le-unknown-freebsd",
1693
            "powerpc64le-unknown-linux-gnu",
1694
            "powerpc64le-unknown-linux-musl",
1695
            "powerpc64-unknown-freebsd",
1696
            "powerpc64-unknown-linux-gnu",
1697
            "powerpc64-unknown-linux-musl",
1698
            "powerpc64-unknown-openbsd",
1699
            "powerpc64-wrs-vxworks",
1700
            "powerpc-ibm-aix",
1701
            "powerpc-unknown-freebsd",
1702
            "powerpc-unknown-linux-gnu",
1703
            "powerpc-unknown-linux-gnuspe",
1704
            "powerpc-unknown-linux-musl",
1705
            "powerpc-unknown-netbsd",
1706
            "powerpc-unknown-openbsd",
1707
            "powerpc-wrs-vxworks",
1708
            "powerpc-wrs-vxworks-spe",
1709
            "riscv32gc-unknown-linux-gnu",
1710
            "riscv32gc-unknown-linux-musl",
1711
            "riscv32imac-esp-espidf",
1712
            "riscv32imac-unknown-none-elf",
1713
            //"riscv32imac-unknown-xous-elf", // TODO
1714
            "riscv32imafc-esp-espidf",
1715
            "riscv32imafc-unknown-none-elf",
1716
            "riscv32ima-unknown-none-elf",
1717
            "riscv32imc-esp-espidf",
1718
            "riscv32imc-unknown-none-elf",
1719
            //"riscv32im-risc0-zkvm-elf", // TODO
1720
            "riscv32im-unknown-none-elf",
1721
            "riscv32i-unknown-none-elf",
1722
            "riscv64gc-unknown-freebsd",
1723
            "riscv64gc-unknown-fuchsia",
1724
            "riscv64gc-unknown-hermit",
1725
            "riscv64gc-unknown-linux-gnu",
1726
            "riscv64gc-unknown-linux-musl",
1727
            "riscv64gc-unknown-netbsd",
1728
            "riscv64gc-unknown-none-elf",
1729
            "riscv64gc-unknown-openbsd",
1730
            "riscv64imac-unknown-none-elf",
1731
            "riscv64-linux-android",
1732
            "s390x-unknown-linux-gnu",
1733
            "s390x-unknown-linux-musl",
1734
            "sparc64-unknown-linux-gnu",
1735
            "sparc64-unknown-netbsd",
1736
            "sparc64-unknown-openbsd",
1737
            "sparc-unknown-linux-gnu",
1738
            "sparc-unknown-none-elf",
1739
            "sparcv9-sun-solaris",
1740
            "thumbv4t-none-eabi",
1741
            "thumbv5te-none-eabi",
1742
            "thumbv6m-none-eabi",
1743
            "thumbv7a-pc-windows-msvc",
1744
            "thumbv7a-uwp-windows-msvc",
1745
            "thumbv7em-none-eabi",
1746
            "thumbv7em-none-eabihf",
1747
            "thumbv7m-none-eabi",
1748
            "thumbv7neon-linux-androideabi",
1749
            "thumbv7neon-unknown-linux-gnueabihf",
1750
            "thumbv7neon-unknown-linux-musleabihf",
1751
            "thumbv8m.base-none-eabi",
1752
            "thumbv8m.main-none-eabi",
1753
            "thumbv8m.main-none-eabihf",
1754
            "wasm32-experimental-emscripten",
1755
            "wasm32-unknown-emscripten",
1756
            "wasm32-unknown-unknown",
1757
            "wasm32-wasi",
1758
            "wasm32-wasip1",
1759
            "wasm32-wasip1-threads",
1760
            "wasm32-wasip2",
1761
            "wasm64-unknown-unknown",
1762
            "wasm64-wasi",
1763
            "x86_64-apple-darwin",
1764
            "x86_64-apple-ios",
1765
            "x86_64-apple-ios-macabi",
1766
            "x86_64-apple-tvos",
1767
            "x86_64-apple-watchos-sim",
1768
            "x86_64-fortanix-unknown-sgx",
1769
            "x86_64h-apple-darwin",
1770
            "x86_64-linux-android",
1771
            //"x86_64-pc-nto-qnx710", // TODO
1772
            "x86_64-linux-kernel", // Changed to x86_64-unknown-none-linuxkernel in 1.53.0
1773
            "x86_64-apple-macosx10.7.0",
1774
            "x86_64-pc-solaris",
1775
            "x86_64-pc-windows-gnu",
1776
            "x86_64-pc-windows-gnullvm",
1777
            "x86_64-pc-windows-msvc",
1778
            "x86_64-rumprun-netbsd", // Removed in 1.53.0
1779
            "x86_64-sun-solaris",
1780
            "x86_64-unknown-bitrig",
1781
            "x86_64-unknown-cloudabi",
1782
            "x86_64-unikraft-linux-musl",
1783
            "x86_64-unknown-dragonfly",
1784
            "x86_64-unknown-freebsd",
1785
            "x86_64-unknown-fuchsia",
1786
            "x86_64-unknown-haiku",
1787
            "x86_64-unknown-hermit-kernel", // Changed to x86_64-unknown-none-hermitkernel in 1.53.0
1788
            "x86_64-unknown-hermit",
1789
            "x86_64-unknown-illumos",
1790
            "x86_64-unknown-l4re-uclibc",
1791
            "x86_64-unknown-linux-gnu",
1792
            "x86_64-unknown-linux-gnux32",
1793
            "x86_64-unknown-linux-musl",
1794
            "x86_64-unknown-linux-none",
1795
            "x86_64-unknown-linux-ohos",
1796
            "x86_64-unknown-netbsd",
1797
            "x86_64-unknown-none",
1798
            "x86_64-unknown-none-hermitkernel",
1799
            "x86_64-unknown-none-linuxkernel",
1800
            "x86_64-unknown-openbsd",
1801
            "x86_64-unknown-redox",
1802
            "x86_64-unknown-uefi",
1803
            "x86_64-uwp-windows-gnu",
1804
            "x86_64-uwp-windows-msvc",
1805
            "x86_64-win7-windows-msvc",
1806
            "x86_64-wrs-vxworks",
1807
            "xtensa-esp32-espidf",
1808
            "clever-unknown-elf",
1809
            "xtensa-esp32-none-elf",
1810
            "xtensa-esp32s2-espidf",
1811
            "xtensa-esp32s2-none-elf",
1812
            "xtensa-esp32s3-espidf",
1813
            "xtensa-esp32s3-none-elf",
1814
            #[cfg(feature = "arch_zkasm")]
1815
            "zkasm-unknown-unknown",
1816
        ];
1817
1818
        for target in targets.iter() {
1819
            let t = Triple::from_str(target).expect("can't parse target");
1820
            assert_ne!(t.architecture, Architecture::Unknown);
1821
            assert_eq!(t.to_string(), *target, "{:#?}", t);
1822
        }
1823
    }
1824
1825
    #[test]
1826
    fn default_format_to_elf() {
1827
        let t = Triple::from_str("riscv64").expect("can't parse target");
1828
        assert_eq!(
1829
            t.architecture,
1830
            Architecture::Riscv64(Riscv64Architecture::Riscv64),
1831
        );
1832
        assert_eq!(t.vendor, Vendor::Unknown);
1833
        assert_eq!(t.operating_system, OperatingSystem::Unknown);
1834
        assert_eq!(t.environment, Environment::Unknown);
1835
        assert_eq!(t.binary_format, BinaryFormat::Elf);
1836
    }
1837
1838
    #[test]
1839
    fn thumbv7em_none_eabihf() {
1840
        let t = Triple::from_str("thumbv7em-none-eabihf").expect("can't parse target");
1841
        assert_eq!(
1842
            t.architecture,
1843
            Architecture::Arm(ArmArchitecture::Thumbv7em)
1844
        );
1845
        assert_eq!(t.vendor, Vendor::Unknown);
1846
        assert_eq!(t.operating_system, OperatingSystem::None_);
1847
        assert_eq!(t.environment, Environment::Eabihf);
1848
        assert_eq!(t.binary_format, BinaryFormat::Elf);
1849
    }
1850
1851
    #[test]
1852
    fn fuchsia_rename() {
1853
        // Fuchsia targets were renamed to add the `unknown`.
1854
        assert_eq!(
1855
            Triple::from_str("aarch64-fuchsia"),
1856
            Triple::from_str("aarch64-unknown-fuchsia")
1857
        );
1858
        assert_eq!(
1859
            Triple::from_str("x86_64-fuchsia"),
1860
            Triple::from_str("x86_64-unknown-fuchsia")
1861
        );
1862
    }
1863
1864
    #[test]
1865
    fn custom_vendors() {
1866
        // Test various invalid cases.
1867
        assert!(Triple::from_str("x86_64--linux").is_err());
1868
        assert!(Triple::from_str("x86_64-42-linux").is_err());
1869
        assert!(Triple::from_str("x86_64-__customvendor__-linux").is_err());
1870
        assert!(Triple::from_str("x86_64-^-linux").is_err());
1871
        assert!(Triple::from_str("x86_64- -linux").is_err());
1872
        assert!(Triple::from_str("x86_64-CustomVendor-linux").is_err());
1873
        assert!(Triple::from_str("x86_64-linux-linux").is_err());
1874
        assert!(Triple::from_str("x86_64-x86_64-linux").is_err());
1875
        assert!(Triple::from_str("x86_64-elf-linux").is_err());
1876
        assert!(Triple::from_str("x86_64-gnu-linux").is_err());
1877
        assert!(Triple::from_str("x86_64-linux-customvendor").is_err());
1878
        assert!(Triple::from_str("customvendor").is_err());
1879
        assert!(Triple::from_str("customvendor-x86_64").is_err());
1880
        assert!(Triple::from_str("x86_64-").is_err());
1881
        assert!(Triple::from_str("x86_64--").is_err());
1882
1883
        // Test various Unicode things.
1884
        assert!(
1885
            Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux").is_err(),
1886
            "unicode font hazard"
1887
        );
1888
        assert!(
1889
            Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux").is_err(),
1890
            "diacritical mark stripping hazard"
1891
        );
1892
        assert!(
1893
            Triple::from_str("x86_64-customvendοr-linux").is_err(),
1894
            "homoglyph hazard"
1895
        );
1896
        assert!(Triple::from_str("x86_64-customvendor-linux").is_ok());
1897
        assert!(
1898
            Triple::from_str("x86_64-ffi-linux").is_err(),
1899
            "normalization hazard"
1900
        );
1901
        assert!(Triple::from_str("x86_64-ffi-linux").is_ok());
1902
        assert!(
1903
            Triple::from_str("x86_64-custom‍vendor-linux").is_err(),
1904
            "zero-width character hazard"
1905
        );
1906
        assert!(
1907
            Triple::from_str("x86_64-customvendor-linux").is_err(),
1908
            "BOM hazard"
1909
        );
1910
1911
        // Test some valid cases.
1912
        let t = Triple::from_str("x86_64-customvendor-linux")
1913
            .expect("can't parse target with custom vendor");
1914
        assert_eq!(t.architecture, Architecture::X86_64);
1915
        assert_eq!(
1916
            t.vendor,
1917
            Vendor::Custom(CustomVendor::Static("customvendor"))
1918
        );
1919
        assert_eq!(t.operating_system, OperatingSystem::Linux);
1920
        assert_eq!(t.environment, Environment::Unknown);
1921
        assert_eq!(t.binary_format, BinaryFormat::Elf);
1922
        assert_eq!(t.to_string(), "x86_64-customvendor-linux");
1923
1924
        let t =
1925
            Triple::from_str("x86_64-customvendor").expect("can't parse target with custom vendor");
1926
        assert_eq!(t.architecture, Architecture::X86_64);
1927
        assert_eq!(
1928
            t.vendor,
1929
            Vendor::Custom(CustomVendor::Static("customvendor"))
1930
        );
1931
        assert_eq!(t.operating_system, OperatingSystem::Unknown);
1932
        assert_eq!(t.environment, Environment::Unknown);
1933
        assert_eq!(t.binary_format, BinaryFormat::Elf);
1934
1935
        assert_eq!(
1936
            Triple::from_str("unknown-foo"),
1937
            Ok(Triple {
1938
                architecture: Architecture::Unknown,
1939
                vendor: Vendor::Custom(CustomVendor::Static("foo")),
1940
                operating_system: OperatingSystem::Unknown,
1941
                environment: Environment::Unknown,
1942
                binary_format: BinaryFormat::Unknown,
1943
            })
1944
        );
1945
    }
1946
}