vmm/cpu_config/
templates_serde.rs1use std::fmt::Debug;
5
6use serde::de::Error as SerdeError;
7use serde::{Deserialize, Deserializer, Serializer};
8
9pub fn serialize_to_hex_str<S, N>(number: &N, serializer: S) -> Result<S::Ok, S::Error>
11where
12 S: Serializer,
13 N: std::fmt::LowerHex + Debug,
14{
15 serializer.serialize_str(format!("{:#x}", number).as_str())
16}
17
18macro_rules! deserialize_from_str {
19 ($name:ident, $type:tt) => {
20 pub fn $name<'de, D>(deserializer: D) -> Result<$type, D::Error>
23 where
24 D: Deserializer<'de>,
25 {
26 let number_str = String::deserialize(deserializer)?;
27 let deserialized_number = if let Some(s) = number_str.strip_prefix("0b") {
28 $type::from_str_radix(s, 2)
29 } else if let Some(s) = number_str.strip_prefix("0x") {
30 $type::from_str_radix(s, 16)
31 } else {
32 return Err(D::Error::custom(format!(
33 "No supported number system prefix found in value [{}]. Make sure to prefix \
34 the number with '0x' for hexadecimal numbers or '0b' for binary numbers.",
35 number_str,
36 )));
37 }
38 .map_err(|err| {
39 D::Error::custom(format!(
40 "Failed to parse string [{}] as a number for CPU template - {:?}",
41 number_str, err
42 ))
43 })?;
44 Ok(deserialized_number)
45 }
46 };
47}
48
49deserialize_from_str!(deserialize_from_str_u32, u32);
50deserialize_from_str!(deserialize_from_str_u64, u64);
51
52#[cfg(test)]
53mod tests {
54 use serde::de::IntoDeserializer;
55 use serde::de::value::{Error, StrDeserializer};
56
57 use super::*;
58
59 #[test]
60 fn test_deserialize_from_str() {
61 let valid_string = "0b1000101";
62 let deserializer: StrDeserializer<Error> = valid_string.into_deserializer();
63 let valid_value = deserialize_from_str_u32(deserializer);
64 assert_eq!(valid_value.unwrap(), 69);
65
66 let valid_string = "0x0045";
67 let deserializer: StrDeserializer<Error> = valid_string.into_deserializer();
68 let valid_value = deserialize_from_str_u32(deserializer);
69 assert_eq!(valid_value.unwrap(), 69);
70
71 let invalid_string = "xϽ69";
72 let deserializer: StrDeserializer<Error> = invalid_string.into_deserializer();
73 let invalid_value = deserialize_from_str_u32(deserializer);
74 invalid_value.unwrap_err();
75
76 let invalid_string = "69";
77 let deserializer: StrDeserializer<Error> = invalid_string.into_deserializer();
78 let invalid_value = deserialize_from_str_u32(deserializer);
79 invalid_value.unwrap_err();
80 }
81}