1use std::{borrow::Cow, fmt, str::FromStr};
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub enum Architecture {
58 X86,
60 X86_64,
62 Arm,
64 Arm64,
66 Arm64_32,
68}
69
70impl FromStr for Architecture {
71 type Err = UnknownArchitecture;
72
73 fn from_str(s: &str) -> Result<Self, Self::Err> {
74 match s.to_lowercase().as_str() {
75 "x86" | "i386" | "i686" => Ok(Self::X86),
76 "x86_64" => Ok(Self::X86_64),
77 "arm" | "armv7" | "armv7s" | "armv7k" => Ok(Self::Arm),
78 "aarch64" | "arm64" => Ok(Self::Arm64),
79 "arm64_32" => Ok(Self::Arm64_32),
80 _ => Err(UnknownArchitecture(s.to_string())),
81 }
82 }
83}
84
85impl fmt::Display for Architecture {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 let s: Cow<'static, str> = match self {
88 Self::X86 => Cow::Borrowed("x86"),
89 Self::X86_64 => Cow::Borrowed("x86_64"),
90 Self::Arm => Cow::Borrowed("arm"),
91 Self::Arm64 => Cow::Borrowed("arm64"),
92 Self::Arm64_32 => Cow::Borrowed("arm64_32"),
93 };
94 write!(f, "{s}")
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
109pub struct UnknownArchitecture(pub String);
110
111impl fmt::Display for UnknownArchitecture {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "unsupported architecture: {:?}", self.0)
114 }
115}
116
117impl std::error::Error for UnknownArchitecture {}
118
119pub fn to_clang(target: &str) -> Option<&'static str> {
135 match target {
136 "aarch64-apple-darwin" => Some("arm64-apple-macosx"),
138 "x86_64-apple-darwin" => Some("x86_64-apple-macosx"),
139
140 "aarch64-apple-ios" => Some("arm64-apple-ios"),
142 "armv7-apple-ios" => Some("armv7-apple-ios"),
143 "armv7s-apple-ios" => Some("armv7s-apple-ios"),
144
145 "aarch64-apple-ios-sim" => Some("arm64-apple-ios-simulator"),
147 "x86_64-apple-ios" => Some("x86_64-apple-ios-simulator"),
148
149 "aarch64-apple-ios-macabi" => Some("arm64-apple-ios-macabi"),
151 "x86_64-apple-ios-macabi" => Some("x86_64-apple-ios-macabi"),
152
153 "aarch64-apple-tvos" => Some("arm64-apple-tvos"),
155 "aarch64-apple-tvos-sim" => Some("arm64-apple-tvos-simulator"),
156 "x86_64-apple-tvos" => Some("x86_64-apple-tvos-simulator"),
157
158 "aarch64-apple-watchos" => Some("arm64-apple-watchos"),
160 "armv7k-apple-watchos" => Some("armv7k-apple-watchos"),
161 "arm64_32-apple-watchos" => Some("arm64_32-apple-watchos"),
162 "aarch64-apple-watchos-sim" => Some("arm64-apple-watchos-simulator"),
163 "x86_64-apple-watchos-sim" => Some("x86_64-apple-watchos-simulator"),
164
165 "aarch64-apple-visionos" => Some("arm64-apple-xros"),
167 "aarch64-apple-visionos-sim" => Some("arm64-apple-xros-simulator"),
168
169 "aarch64-apple-driverkit" => Some("arm64-apple-driverkit"),
171 "x86_64-apple-driverkit" => Some("x86_64-apple-driverkit"),
172
173 _ => None,
174 }
175}
176
177pub fn to_sdk(target: &str) -> Option<&'static str> {
195 crate::platform::ApplePlatform::from_rust_triple(target)
197 .ok()
198 .and_then(|p| p.sdk())
199}
200
201#[cfg(test)]
204mod tests {
205 use super::*;
206
207 #[test]
210 fn parse_architectures() {
211 assert_eq!("aarch64".parse::<Architecture>().unwrap(), Architecture::Arm64);
212 assert_eq!("x86_64".parse::<Architecture>().unwrap(), Architecture::X86_64);
213 assert_eq!("armv7".parse::<Architecture>().unwrap(), Architecture::Arm);
214 assert_eq!("arm64_32".parse::<Architecture>().unwrap(), Architecture::Arm64_32);
215 let err = "riscv64".parse::<Architecture>().unwrap_err();
216 assert!(err.to_string().contains("riscv64"));
217 }
218
219 #[test]
220 fn architecture_display() {
221 assert_eq!(format!("{}", Architecture::Arm64), "arm64");
222 assert_eq!(format!("{}", Architecture::X86_64), "x86_64");
223 assert_eq!(format!("{}", Architecture::Arm64_32), "arm64_32");
224 }
225
226 #[test]
229 fn clang_macos() {
230 assert_eq!(to_clang("aarch64-apple-darwin"), Some("arm64-apple-macosx"));
231 assert_eq!(to_clang("x86_64-apple-darwin"), Some("x86_64-apple-macosx"));
232 }
233
234 #[test]
235 fn clang_ios() {
236 assert_eq!(to_clang("aarch64-apple-ios"), Some("arm64-apple-ios"));
237 assert_eq!(to_clang("aarch64-apple-ios-sim"), Some("arm64-apple-ios-simulator"));
238 assert_eq!(to_clang("x86_64-apple-ios"), Some("x86_64-apple-ios-simulator"));
239 }
240
241 #[test]
242 fn clang_visionos() {
243 assert_eq!(to_clang("aarch64-apple-visionos"), Some("arm64-apple-xros"));
244 assert_eq!(to_clang("aarch64-apple-visionos-sim"), Some("arm64-apple-xros-simulator"));
245 }
246
247 #[test]
248 fn clang_catalyst() {
249 assert_eq!(to_clang("aarch64-apple-ios-macabi"), Some("arm64-apple-ios-macabi"));
250 }
251
252 #[test]
253 fn clang_watchos() {
254 assert_eq!(to_clang("aarch64-apple-watchos"), Some("arm64-apple-watchos"));
255 assert_eq!(to_clang("armv7k-apple-watchos"), Some("armv7k-apple-watchos"));
256 assert_eq!(to_clang("arm64_32-apple-watchos"), Some("arm64_32-apple-watchos"));
257 assert_eq!(to_clang("aarch64-apple-watchos-sim"), Some("arm64-apple-watchos-simulator"));
258 }
259
260 #[test]
261 fn clang_driverkit() {
262 assert_eq!(to_clang("aarch64-apple-driverkit"), Some("arm64-apple-driverkit"));
263 assert_eq!(to_clang("x86_64-apple-driverkit"), Some("x86_64-apple-driverkit"));
264 }
265
266 #[test]
267 fn clang_unknown_is_none() {
268 assert_eq!(to_clang("x86_64-unknown-linux-gnu"), None);
269 assert_eq!(to_clang("aarch64-unknown-linux-musl"), None);
270 assert_eq!(to_clang(""), None);
271 }
272
273 #[test]
276 fn sdk_macos() {
277 assert_eq!(to_sdk("aarch64-apple-darwin"), Some("macosx"));
278 assert_eq!(to_sdk("x86_64-apple-darwin"), Some("macosx"));
279 }
280
281 #[test]
282 fn sdk_ios() {
283 assert_eq!(to_sdk("aarch64-apple-ios"), Some("iphoneos"));
284 assert_eq!(to_sdk("aarch64-apple-ios-sim"), Some("iphonesimulator"));
285 assert_eq!(to_sdk("x86_64-apple-ios"), Some("iphonesimulator"));
286 }
287
288 #[test]
289 fn sdk_visionos() {
290 assert_eq!(to_sdk("aarch64-apple-visionos"), Some("xros"));
291 assert_eq!(to_sdk("aarch64-apple-visionos-sim"), Some("xrsimulator"));
292 }
293
294 #[test]
295 fn sdk_tvos() {
296 assert_eq!(to_sdk("aarch64-apple-tvos"), Some("appletvos"));
297 assert_eq!(to_sdk("aarch64-apple-tvos-sim"), Some("appletvsimulator"));
298 }
299
300 #[test]
301 fn sdk_watchos() {
302 assert_eq!(to_sdk("aarch64-apple-watchos"), Some("watchos"));
303 assert_eq!(to_sdk("aarch64-apple-watchos-sim"), Some("watchsimulator"));
304 }
305
306 #[test]
307 fn sdk_catalyst() {
308 assert_eq!(to_sdk("aarch64-apple-ios-macabi"), Some("macosx"));
310 }
311
312 #[test]
313 fn sdk_unknown_is_none() {
314 assert_eq!(to_sdk("x86_64-unknown-linux-gnu"), None);
315 assert_eq!(to_sdk(""), None);
316 }
317}