Repository: firecracker-microvm/firecracker
File: src/vmm/src/arch/aarch64/regs.rs (Rust)

Code before:
        T::from_slice(self.data)
    }

    /// Returns a string with hex formatted value of the register.
    pub fn value_str(&self) -> String {
        fn byte_to_hex(byte: u8) -> (u8, u8) {
            static HEX_TABLE: [u8; 16] = [
                b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd',
                b'e', b'f',
            ];

            let hi = HEX_TABLE[(byte >> 4) as usize];
            let lo = HEX_TABLE[(byte & 0xF) as usize];
            (hi, lo)
        }
        let s = self
            .data
            .iter()
            .rev()
            .flat_map(|v| {
                let (hi, lo) = byte_to_hex(*v);
                [hi, lo]
            })
            .collect();
        // SAFETY: all bytes in the array are valid utf-8
        let hex = unsafe { String::from_utf8_unchecked(s) };
        format!("0x{hex}")
    }

    /// Returns register data as a byte slice
    pub fn as_slice(&self) -> &[u8] {
        self.data
    }
}

/// Reference to the aarch64 register.
#[derive(Debug, PartialEq, Eq)]
pub struct Aarch64RegisterRefMut<'a> {
    /// ID of the register
    pub id: u64,
    data: &'a mut [u8],
}

impl<'a> Aarch64RegisterRefMut<'a> {
    /// Creates new register reference with provided id and data.
    /// Register size in `id` should be equal to the
    /// length of the slice. Otherwise this method
    /// will panic.
    pub fn new(id: u64, data: &'a mut [u8]) -> Self {
        assert_eq!(
            reg_size(id),

Review comment (suggestion):
```suggestion
        let hex = self.data.iter().rev().map(|b| format!("{:02x}", b)).collect::<String>();
```

Code after:
    pub fn value<T: Aarch64RegisterData<N>, const N: usize>(&self) -> T {
        T::from_slice(self.data)
    }

    /// Returns a string with hex formatted value of the register.
    pub fn value_str(&self) -> String {
        let hex = self.data.iter().rev().fold(String::new(), |mut acc, byte| {
            write!(&mut acc, "{:02x}", byte).unwrap();
            acc
        });
        format!("0x{hex}")
    }

    /// Returns register data as a byte slice
    pub fn as_slice(&self) -> &[u8] {
        self.data
    }
}

/// Reference to the aarch64 register.
#[derive(Debug, PartialEq, Eq)]
pub struct Aarch64RegisterRefMut<'a> {
    /// ID of the register
    pub id: u64,
    data: &'a mut [u8],
}

impl<'a> Aarch64RegisterRefMut<'a> {
    /// Creates new register reference with provided id and data.
    /// Register size in `id` should be equal to the
    /// length of the slice. Otherwise this method
    /// will panic.
    pub fn new(id: u64, data: &'a mut [u8]) -> Self {
        assert_eq!(
            reg_size(id),
            data.len(),
            "Attempt to create a register reference with incompatible id and data length"
        );

        Self { id, data }
    }

    /// Returns register size in bytes
    pub fn size(&self) -> RegSize {
        reg_size(self.id).into()
    }

    /// Returns a register value.
    /// Type `T` must be of the same length as an
    /// underlying data slice. Otherwise this method
    /// will panic.