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