1#[macro_export]
2macro_rules! declare_field_accessors {
3 ($(#[$fattr:meta])* $fname: ident, $ftype: ty [padding]) => {};
4 ($(#[$fattr:meta])* $fname: ident, $ftype: ty [readonly]) => {
5 $(#[$fattr])*
6 #[inline]
7 pub fn $fname(&self) -> $ftype {
8 unsafe { core::ptr::read_volatile(core::ptr::addr_of!(self.$fname)) }
9 }
10 };
11 ($(#[$fattr:meta])* $fname: ident, $ftype: ty [writeonly]) => {
12 paste::paste! {
13 $(#[$fattr])*
14 #[inline]
15 pub fn [<set_ $fname>](&mut self, value: $ftype) {
16 unsafe {
17 core::ptr::write_volatile(core::ptr::addr_of_mut!(self.$fname), value);
18 }
19 }
20 }
21 };
22 ($(#[$fattr:meta])* $fname: ident, $ftype: ty []) => {
23 paste::paste! {
24 $(#[$fattr])*
25 #[inline]
26 pub fn $fname(&self) -> $ftype {
27 unsafe { core::ptr::read_volatile(core::ptr::addr_of!(self.$fname)) }
28 }
29
30 $(#[$fattr])*
31 #[inline]
32 pub fn [<set_ $fname>](&mut self, value: $ftype) {
33 unsafe {
34 core::ptr::write_volatile(core::ptr::addr_of_mut!(self.$fname), value);
35 }
36 }
37
38 paste::paste! {
39 $(#[$fattr])*
40 #[inline]
41 pub fn [<update_ $fname>](&mut self, f: impl FnOnce(&mut $ftype)) {
42 let mut value = self.$fname();
43 f(&mut value);
44 self.[<set_ $fname>](value);
45 }
46 }
47 }
48 };
49}
50
51#[macro_export]
52macro_rules! declare_volatile_struct {
53 (
54 $(#[$sattr:meta])*
55 pub struct $sname: ident {
56 $(
57 $(#[$fattr:meta])*
58 $([$($tags: ident)*])? $fname: ident: $ftype: ty,
59 )*
60 }
61 ) => {
62 $(#[$sattr])*
63 pub struct $sname {
64 $(
65 $(#[$fattr])*
66 $fname: $ftype,
67 )*
68 }
69
70 impl $sname {
71 $(
72 $crate::declare_field_accessors!($(#[$fattr])* $fname, $ftype [$($($tags)*)?]);
73 )*
74 }
75 };
76}