mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
arch: Helper functions for 64-bit hex (de-)serialization
We create 64-bit analogues of the already existing hex (de-)serializer helper functions for the 32-bit case. These are necessary because the CPU profile needs associated data describing how to adjust feature MSRs whose values are 64-bits. In this case we prefer some small amount of code duplication over macros and/or traits since we do not expect the need for further variants of these helpers. Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de> On-behalf-of: SAP oliver.anderson@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
2eb64a2b4f
commit
838d01b0bc
@@ -3,8 +3,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use std::result;
|
||||
|
||||
use serde::{Deserialize, Deserializer, Serializer, de};
|
||||
|
||||
/// Serializes the given `input` as a hex string (starting with "0x").
|
||||
@@ -14,22 +12,42 @@ use serde::{Deserialize, Deserializer, Serializer, de};
|
||||
pub(crate) fn serialize_u32_hex<S: Serializer>(
|
||||
input: &u32,
|
||||
serializer: S,
|
||||
) -> result::Result<S::Ok, S::Error> {
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&format!("{input:#x}"))
|
||||
}
|
||||
|
||||
/// Deserializes a u32 from a hex string representation.
|
||||
pub(crate) fn deserialize_u32_hex<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> result::Result<u32, D::Error> {
|
||||
) -> Result<u32, D::Error> {
|
||||
let hex: &str = <&str>::deserialize(deserializer)?;
|
||||
u32::from_str_radix(hex.strip_prefix("0x").unwrap_or(""), 16).map_err(|_| {
|
||||
<D::Error as de::Error>::custom(format!("{hex} is not a hex encoded 32 bit integer"))
|
||||
})
|
||||
}
|
||||
|
||||
/// 64-bit version of `serialize_u32_hex`
|
||||
pub(crate) fn serialize_u64_hex<S: Serializer>(
|
||||
input: &u64,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(&format!("{input:#x}"))
|
||||
}
|
||||
|
||||
/// 64-bit version of `deserialize_u32_hex`
|
||||
pub(crate) fn deserialize_u64_hex<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<u64, D::Error> {
|
||||
let hex: &str = <&str>::deserialize(deserializer)?;
|
||||
u64::from_str_radix(hex.strip_prefix("0x").unwrap_or(""), 16).map_err(|_| {
|
||||
<D::Error as de::Error>::custom(format!("{hex} is not a hex encoded 64 bit integer"))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_tests {
|
||||
use std::fmt::Debug;
|
||||
|
||||
use proptest::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -49,15 +67,29 @@ mod unit_tests {
|
||||
bar: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
struct TestStruct64 {
|
||||
#[serde(
|
||||
serialize_with = "serialize_u64_hex",
|
||||
deserialize_with = "deserialize_u64_hex"
|
||||
)]
|
||||
foo: u64,
|
||||
#[serde(
|
||||
serialize_with = "serialize_u64_hex",
|
||||
deserialize_with = "deserialize_u64_hex"
|
||||
)]
|
||||
bar: u64,
|
||||
}
|
||||
|
||||
// Check that our hex serializers satisfy the two following invariants
|
||||
// 1. Serialization followed by deserialization is the identity.
|
||||
// 2. Values of type u32 are serialized to strings starting with "0x" and then
|
||||
// 2. Values of type u32/u64 are serialized to strings starting with "0x" and then
|
||||
// a sub-string where all characters are ascii hex digits (with the letters [a-f] always in lowercase).
|
||||
proptest! {
|
||||
#[test]
|
||||
fn hex_serialization_works(foo in any::<u32>(), bar in any::<u32>()) {
|
||||
let t = TestStruct { foo , bar };
|
||||
|
||||
fn test_hex_serialization<T>(t: T) -> Result<(), TestCaseError>
|
||||
where
|
||||
T: Serialize + Debug + Eq + Copy,
|
||||
for<'de> T: Deserialize<'de>,
|
||||
{
|
||||
let t_string = serde_json::to_string(&t).unwrap();
|
||||
let t_deserialized = serde_json::from_str(&t_string).unwrap();
|
||||
prop_assert_eq!(t, t_deserialized);
|
||||
@@ -76,7 +108,22 @@ mod unit_tests {
|
||||
|
||||
check_str_invariants(foo_str)?;
|
||||
check_str_invariants(bar_str)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn hex_serialization_works_32(foo in any::<u32>(), bar in any::<u32>()) {
|
||||
let t = TestStruct { foo , bar };
|
||||
test_hex_serialization(t)?;
|
||||
}
|
||||
}
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn hex_serialization_works_64(foo in any::<u64>(), bar in any::<u64>()) {
|
||||
let t = TestStruct64 { foo , bar };
|
||||
test_hex_serialization(t)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user