memacc/memman/
modify_address_value.rs1use super::ReadFromAddress;
2use super::WriteToAddress;
3
4pub trait ModifyAddressValue {
5 type Word;
6 fn modify_address_value<F>(self, f: F)
7 where
8 F: FnOnce(&Self::Word) -> Self::Word;
9}
10
11macro_rules! ImplementModifyAddressValue {
13 ($type:ty) => {
14 impl ModifyAddressValue for *mut $type {
15 type Word = $type;
16 #[inline]
17 fn modify_address_value<F>(self, f: F)
18 where
19 F: FnOnce(&Self::Word) -> Self::Word,
20 {
21 let value_old = self.read_from_address();
22 let value_new = f(&value_old);
23 self.write_to_address(value_new);
24 }
25 }
26 };
27}
28
29ImplementModifyAddressValue!(u8);
30ImplementModifyAddressValue!(u16);
31ImplementModifyAddressValue!(u32);
32ImplementModifyAddressValue!(u64);
33
34#[cfg(test)]
35mod tests {
36 use crate::bitman::SetBit;
37 use crate::bitman::SetBits;
38 use crate::memman::ReadFromAddress;
39
40 use super::ModifyAddressValue;
41
42 #[test]
43 fn test_modify_address_value_0() {
44 let mut value = 0b0000_0000u8;
45 let reference = &mut value;
46 let address = reference as *mut u8;
47 address.modify_address_value(|w| w.set_bit(0));
48 assert_eq!(address.read_from_address(), 0b0000_0001);
49 }
50
51 #[test]
52 fn test_modify_address_value_1() {
53 let mut value = 0b0000_0000u8;
54 let reference = &mut value;
55 let address = reference as *mut u8;
56 address.modify_address_value(|w| w.set_bits(0..=1));
57 assert_eq!(address.read_from_address(), 0b0000_0011);
58 }
59
60 #[test]
61 fn test_modify_address_value_2() {
62 let mut value = 0b0000_0000u8;
63 let reference = &mut value;
64 let address = reference as *mut u8;
65 let action = |w: &u8| w.set_bit(0);
66 address.modify_address_value(action);
67 assert_eq!(address.read_from_address(), 0b0000_0001);
68 }
69
70 #[test]
71 fn test_modify_address_value_3() {
72 let mut value = 0b0000_0000u8;
73 let reference = &mut value;
74 let address = reference as *mut u8;
75 let action = |w: &u8| w.set_bits(0..=1);
76 address.modify_address_value(action);
77 assert_eq!(address.read_from_address(), 0b0000_0011);
78 }
79}