1 //! Rust architectures
2 
3 use crate::error::Error;
4 use core::{fmt, str::FromStr};
5 
6 #[cfg(feature = "serde")]
7 use serde::{de, ser, Deserialize, Serialize};
8 
9 /// `target_arch`: Target CPU architecture
10 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
11 #[non_exhaustive]
12 pub enum Arch {
13     /// `aarch64`: ARMv8 64-bit architecture
14     AARCH64,
15 
16     /// `arm`: 32-bit ARM architecture
17     ARM,
18 
19     /// `asm`: asm.js output
20     ASMJS,
21 
22     /// `mips`: 32-bit MIPS CPU architecture
23     MIPS,
24 
25     /// `mips64`: 64-bit MIPS CPU architecture
26     MIPS64,
27 
28     /// `msp430`: 16-bit MSP430 microcontrollers
29     MSP430,
30 
31     /// `nvptx64`: 64-bit NVIDIA PTX
32     NVPTX64,
33 
34     /// `powerpc`: 32-bit POWERPC platform
35     POWERPC,
36 
37     /// `powerpc64`: 64-bit POWERPC platform
38     POWERPC64,
39 
40     /// `riscv`: RISC-V CPU architecture
41     RISCV,
42 
43     /// `s390x`: 64-bit IBM z/Architecture
44     S390X,
45 
46     /// `sparc`: 32-bit SPARC CPU architecture
47     SPARC,
48 
49     /// `sparc64`: 64-bit SPARC CPU architecture
50     SPARC64,
51 
52     /// `thumbv6`: 16-bit ARM CPU architecture subset
53     THUMBV6,
54 
55     /// `thumbv7`: 16-bit ARM CPU architecture subset
56     THUMBV7,
57 
58     /// `wasm32`: Web Assembly (32-bit)
59     WASM32,
60 
61     /// `x86`: Generic x86 CPU architecture
62     X86,
63 
64     /// `x86_64`: "AMD64" CPU architecture
65     X86_64,
66 
67     /// Unknown CPU architecture
68     Unknown,
69 }
70 
71 impl Arch {
72     /// String representing this target architecture which matches `cfg(target_arch)`
as_str(self) -> &'static str73     pub fn as_str(self) -> &'static str {
74         match self {
75             Arch::AARCH64 => "aarch64",
76             Arch::ARM => "arm",
77             Arch::ASMJS => "asmjs",
78             Arch::MIPS => "mips",
79             Arch::MIPS64 => "mips64",
80             Arch::MSP430 => "msp430",
81             Arch::NVPTX64 => "nvptx64",
82             Arch::POWERPC => "powerpc",
83             Arch::POWERPC64 => "powerpc64",
84             Arch::RISCV => "riscv",
85             Arch::S390X => "s390x",
86             Arch::SPARC => "sparc",
87             Arch::SPARC64 => "sparc64",
88             Arch::THUMBV6 => "thumbv6",
89             Arch::THUMBV7 => "thumbv7",
90             Arch::WASM32 => "wasm32",
91             Arch::X86 => "x86",
92             Arch::X86_64 => "x86_64",
93             Arch::Unknown => "unknown",
94         }
95     }
96 }
97 
98 impl FromStr for Arch {
99     type Err = Error;
100 
101     /// Create a new `Arch` from the given string
from_str(arch_name: &str) -> Result<Self, Self::Err>102     fn from_str(arch_name: &str) -> Result<Self, Self::Err> {
103         let arch = match arch_name {
104             "aarch64" => Arch::AARCH64,
105             "arm" => Arch::ARM,
106             "asmjs" => Arch::ASMJS,
107             "mips" => Arch::MIPS,
108             "mips64" => Arch::MIPS64,
109             "msp430" => Arch::MSP430,
110             "nvptx64" => Arch::NVPTX64,
111             "powerpc" => Arch::POWERPC,
112             "powerpc64" => Arch::POWERPC64,
113             "riscv" => Arch::RISCV,
114             "s390x" => Arch::S390X,
115             "sparc" => Arch::SPARC,
116             "sparc64" => Arch::SPARC64,
117             "thumbv6" => Arch::THUMBV6,
118             "thumbv7" => Arch::THUMBV7,
119             "wasm32" => Arch::WASM32,
120             "x86" => Arch::X86,
121             "x86_64" => Arch::X86_64,
122             _ => return Err(Error),
123         };
124 
125         Ok(arch)
126     }
127 }
128 
129 impl fmt::Display for Arch {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result130     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131         f.write_str(self.as_str())
132     }
133 }
134 
135 #[cfg(feature = "serde")]
136 impl Serialize for Arch {
serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>137     fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
138         serializer.serialize_str(self.as_str())
139     }
140 }
141 
142 #[cfg(feature = "serde")]
143 impl<'de> Deserialize<'de> for Arch {
deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>144     fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
145         Ok(<&str>::deserialize(deserializer)?
146             .parse()
147             .unwrap_or(Arch::Unknown))
148     }
149 }
150 
151 // Detect and expose `target_arch` as a constant
152 // Whether this is a good idea is somewhat debatable
153 
154 #[cfg(target_arch = "aarch64")]
155 /// `target_arch` when building this crate: `x86_64`
156 pub const TARGET_ARCH: Arch = Arch::AARCH64;
157 
158 #[cfg(target_arch = "arm")]
159 /// `target_arch` when building this crate: `arm`
160 pub const TARGET_ARCH: Arch = Arch::ARM;
161 
162 #[cfg(target_arch = "asmjs")]
163 /// `target_arch` when building this crate: `asmjs`
164 pub const TARGET_ARCH: Arch = Arch::ASMJS;
165 
166 #[cfg(target_arch = "mips")]
167 /// `target_arch` when building this crate: `mips`
168 pub const TARGET_ARCH: Arch = Arch::MIPS;
169 
170 #[cfg(target_arch = "mips64")]
171 /// `target_arch` when building this crate: `mips64`
172 pub const TARGET_ARCH: Arch = Arch::MIPS64;
173 
174 #[cfg(target_arch = "msp430")]
175 /// `target_arch` when building this crate: `msp430`
176 pub const TARGET_ARCH: Arch = Arch::MSP430;
177 
178 #[cfg(target_arch = "nvptx64")]
179 /// `target_arch` when building this crate: `nvptx64`
180 pub const TARGET_ARCH: Arch = Arch::NVPTX64;
181 
182 #[cfg(target_arch = "powerpc")]
183 /// `target_arch` when building this crate: `powerpc`
184 pub const TARGET_ARCH: Arch = Arch::POWERPC;
185 
186 #[cfg(target_arch = "powerpc64")]
187 /// `target_arch` when building this crate: `powerpc64`
188 pub const TARGET_ARCH: Arch = Arch::POWERPC64;
189 
190 #[cfg(target_arch = "riscv")]
191 /// `target_arch` when building this crate: `riscv`
192 pub const TARGET_ARCH: Arch = Arch::RISCV;
193 
194 #[cfg(target_arch = "s390x")]
195 /// `target_arch` when building this crate: `s390x`
196 pub const TARGET_ARCH: Arch = Arch::S390X;
197 
198 #[cfg(target_arch = "sparc")]
199 /// `target_arch` when building this crate: `sparc`
200 pub const TARGET_ARCH: Arch = Arch::SPARC;
201 
202 #[cfg(target_arch = "sparc64")]
203 /// `target_arch` when building this crate: `sparc64`
204 pub const TARGET_ARCH: Arch = Arch::SPARC64;
205 
206 #[cfg(target_arch = "wasm32")]
207 /// `target_arch` when building this crate: `wasm32`
208 pub const TARGET_ARCH: Arch = Arch::WASM32;
209 
210 #[cfg(target_arch = "x86")]
211 /// `target_arch` when building this crate: `x86`
212 pub const TARGET_ARCH: Arch = Arch::X86;
213 
214 #[cfg(target_arch = "x86_64")]
215 /// `target_arch` when building this crate: `x86_64`
216 pub const TARGET_ARCH: Arch = Arch::X86_64;
217 
218 #[cfg(not(any(
219     target_arch = "aarch64",
220     target_arch = "arm",
221     target_arch = "asmjs",
222     target_arch = "mips",
223     target_arch = "mips64",
224     target_arch = "nvptx64",
225     target_arch = "powerpc",
226     target_arch = "powerpc64",
227     target_arch = "riscv",
228     target_arch = "s390x",
229     target_arch = "sparc",
230     target_arch = "sparc64",
231     target_arch = "wasm32",
232     target_arch = "x86",
233     target_arch = "x86_64"
234 )))]
235 /// `target_arch` when building this crate: unknown!
236 pub const TARGET_ARCH: Arch = Arch::Unknown;
237