xref: /DADK/dadk-config/src/common/target_arch.rs (revision c6f35e8aa5fda2a3004763828fb91c7762df6087)
1 use serde::{Deserialize, Deserializer, Serialize};
2 
3 /// 目标处理器架构
4 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord)]
5 pub enum TargetArch {
6     #[default]
7     X86_64,
8     RiscV64,
9     AArch64,
10 }
11 
12 impl TargetArch {
13     /// 期望的目标处理器架构(如果修改了枚举,那一定要修改这里)
14     pub const EXPECTED: [&'static str; 3] = ["x86_64", "riscv64", "aarch64"];
15 }
16 
17 impl TryFrom<&str> for TargetArch {
18     type Error = String;
19 
20     fn try_from(value: &str) -> Result<Self, Self::Error> {
21         match value.trim().to_ascii_lowercase().as_str() {
22             "x86_64" => Ok(TargetArch::X86_64),
23             "riscv64" => Ok(TargetArch::RiscV64),
24             "aarch64" => Ok(TargetArch::AArch64),
25             _ => Err(format!("Unknown target arch: {}", value)),
26         }
27     }
28 }
29 
30 impl From<TargetArch> for &str {
31     fn from(val: TargetArch) -> Self {
32         match val {
33             TargetArch::X86_64 => "x86_64",
34             TargetArch::RiscV64 => "riscv64",
35             TargetArch::AArch64 => "aarch64",
36         }
37     }
38 }
39 
40 impl From<TargetArch> for String {
41     fn from(val: TargetArch) -> Self {
42         let x: &str = val.into();
43         x.to_string()
44     }
45 }
46 
47 impl<'de> Deserialize<'de> for TargetArch {
48     fn deserialize<D>(deserializer: D) -> Result<TargetArch, D::Error>
49     where
50         D: Deserializer<'de>,
51     {
52         let s = String::deserialize(deserializer)?;
53 
54         let r = TargetArch::try_from(s.as_str());
55         match r {
56             Ok(v) => Ok(v),
57             Err(_) => Err(serde::de::Error::invalid_value(
58                 serde::de::Unexpected::Str(s.as_str()),
59                 &format!("Expected one of {:?}", TargetArch::EXPECTED).as_str(),
60             )),
61         }
62     }
63 }
64 
65 impl Serialize for TargetArch {
66     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67     where
68         S: serde::Serializer,
69     {
70         let string: String = Into::into(*self);
71         serializer.serialize_str(string.as_str())
72     }
73 }
74 
75 #[cfg(test)]
76 mod tests {
77     use super::*;
78     use serde_json;
79 
80     #[test]
81     fn test_default() {
82         let default_arch = TargetArch::default();
83         assert_eq!(default_arch, TargetArch::X86_64);
84     }
85 
86     #[test]
87     fn test_try_from_valid() {
88         let x86_64 = TargetArch::try_from("x86_64").unwrap();
89         assert_eq!(x86_64, TargetArch::X86_64);
90 
91         let riscv64 = TargetArch::try_from("riscv64").unwrap();
92         assert_eq!(riscv64, TargetArch::RiscV64);
93 
94         let aarch64 = TargetArch::try_from("aarch64").unwrap();
95         assert_eq!(aarch64, TargetArch::AArch64);
96     }
97 
98     #[test]
99     fn test_try_from_invalid() {
100         let result = TargetArch::try_from("unknown");
101         assert!(result.is_err());
102         assert_eq!(result.unwrap_err(), "Unknown target arch: unknown");
103     }
104 
105     #[test]
106     fn test_into_str() {
107         let x86_64: &str = TargetArch::X86_64.into();
108         assert_eq!(x86_64, "x86_64");
109 
110         let riscv64: &str = TargetArch::RiscV64.into();
111         assert_eq!(riscv64, "riscv64");
112     }
113 
114     #[test]
115     fn test_into_string() {
116         let x86_64: String = TargetArch::X86_64.into();
117         assert_eq!(x86_64, "x86_64");
118 
119         let riscv64: String = TargetArch::RiscV64.into();
120         assert_eq!(riscv64, "riscv64");
121     }
122 
123     #[test]
124     fn test_deserialize_valid() {
125         let json_x86_64 = r#""x86_64""#;
126         let x86_64: TargetArch = serde_json::from_str(json_x86_64).unwrap();
127         assert_eq!(x86_64, TargetArch::X86_64);
128 
129         let json_riscv64 = r#""riscv64""#;
130         let riscv64: TargetArch = serde_json::from_str(json_riscv64).unwrap();
131         assert_eq!(riscv64, TargetArch::RiscV64);
132     }
133 
134     #[test]
135     fn test_deserialize_invalid() {
136         let json_unknown = r#""unknown""#;
137         let result: Result<TargetArch, _> = serde_json::from_str(json_unknown);
138         assert!(result.is_err());
139     }
140 
141     #[test]
142     fn test_serialize() {
143         let x86_64 = TargetArch::X86_64;
144         let serialized_x86_64 = serde_json::to_string(&x86_64).unwrap();
145         assert_eq!(serialized_x86_64, r#""x86_64""#);
146 
147         let riscv64 = TargetArch::RiscV64;
148         let serialized_riscv64 = serde_json::to_string(&riscv64).unwrap();
149         assert_eq!(serialized_riscv64, r#""riscv64""#);
150     }
151 }
152