memacc/memman/
read_from_address.rs

1pub trait ReadFromAddress {
2    type Type;
3    fn read_from_address(self) -> Self::Type;
4}
5
6/// Implement [`ReadFromAddress`] for given type.
7macro_rules! ImplementReadFromAddress {
8    ($type:ty) => {
9        impl ReadFromAddress for *mut $type {
10            type Type = $type;
11            #[allow(clippy::not_unsafe_ptr_arg_deref)]
12            fn read_from_address(self) -> Self::Type {
13                // SAFETY:
14                // Programmer is responsible for reading from valid address.
15                unsafe { self.read_volatile() }
16            }
17        }
18    };
19}
20
21ImplementReadFromAddress!(u8);
22ImplementReadFromAddress!(u16);
23ImplementReadFromAddress!(u32);
24ImplementReadFromAddress!(u64);
25
26#[cfg(test)]
27mod tests {
28    use super::ReadFromAddress;
29
30    #[test]
31    fn test_read_from_address_u8() {
32        let mut value = 0b1010_0110u8;
33        let reference = &mut value;
34        let address = reference as *mut u8;
35        assert_eq!(address.read_from_address(), value);
36    }
37
38    #[test]
39    fn test_read_from_address_u16() {
40        let mut value = 0b1010_0110_1010_0110u16;
41        let reference = &mut value;
42        let address = reference as *mut u16;
43        assert_eq!(address.read_from_address(), value);
44    }
45
46    #[test]
47    fn test_read_from_address_u32() {
48        let mut value = 0b1010_0110_1010_0110_1010_0110_1010_0110u32;
49        let reference = &mut value;
50        let address = reference as *mut u32;
51        assert_eq!(address.read_from_address(), value);
52    }
53
54    #[test]
55    fn test_read_from_address_u64() {
56        let mut value =
57            0b1010_0110_1010_0110_1010_0110_1010_0110_1010_0110_1010_0110_1010_0110_1010_0110u64;
58        let reference = &mut value;
59        let address = reference as *mut u64;
60        assert_eq!(address.read_from_address(), value);
61    }
62}