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