mj_controller/targets/
platform.rs1use super::*;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum TargetOs {
5 Linux,
6 Darwin,
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct TargetPlatform {
13 pub os: TargetOs,
14 pub architecture: &'static str,
15}
16
17impl TargetPlatform {
18 pub fn parse(uname: &str) -> Result<Self> {
19 let mut fields = uname.split_whitespace();
20 let os = match fields.next() {
21 Some("Linux") => TargetOs::Linux,
22 Some("Darwin") => TargetOs::Darwin,
23 other => bail!("unsupported target operating system {other:?}"),
24 };
25 let architecture = normalize_architecture(fields.next().unwrap_or_default())?;
26 ensure!(
27 fields.next().is_none(),
28 "invalid target platform response {uname:?}"
29 );
30 Ok(Self { os, architecture })
31 }
32}
33
34pub fn normalize_architecture(architecture: &str) -> Result<&'static str> {
35 match architecture {
36 "x86_64" | "amd64" => Ok("x86_64"),
37 "aarch64" | "arm64" => Ok("aarch64"),
38 other => bail!("unsupported target architecture {other:?}"),
39 }
40}
41
42pub fn platform_probe(locator: &TargetLocator) -> CommandSpec {
43 locator_command(locator, vec!["uname".into(), "-sm".into()]).purpose("detect target platform")
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn detects_supported_platforms_and_rejects_unknown_responses() {
52 for (text, os, architecture) in [
53 ("Darwin arm64\n", TargetOs::Darwin, "aarch64"),
54 ("Darwin x86_64\n", TargetOs::Darwin, "x86_64"),
55 ("Linux aarch64\n", TargetOs::Linux, "aarch64"),
56 ("Linux x86_64\n", TargetOs::Linux, "x86_64"),
57 ] {
58 assert_eq!(
59 TargetPlatform::parse(text).unwrap(),
60 TargetPlatform { os, architecture }
61 );
62 }
63 for text in [
64 "FreeBSD arm64",
65 "Linux riscv64",
66 "Darwin",
67 "",
68 "Linux x86_64 junk",
69 ] {
70 assert!(TargetPlatform::parse(text).is_err(), "{text}");
71 }
72 }
73}