Skip to content

Commit e21d5a0

Browse files
committed
feat: implement derive macro for all access types
Signed-off-by: Martin Kröning <[email protected]>
1 parent e68e60a commit e21d5a0

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

volatile-macro/src/lib.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ mod volatile;
5252
///
5353
/// // A real device might have changed the value, though.
5454
/// assert_eq!(volatile_ptr.feature().read(), 0);
55+
///
56+
/// // You can also use shared references.
57+
/// let volatile_ptr = volatile_ref.as_ptr();
58+
/// assert_eq!(volatile_ptr.feature_select().read(), 42);
59+
/// // This does not compile, because `volatile_ptr` is `ReadOnly`.
60+
/// // volatile_ptr.feature_select().write(42);
5561
/// ```
5662
///
5763
/// # Details
@@ -65,21 +71,31 @@ mod volatile;
6571
/// # feature_select: u32,
6672
/// # feature: u32,
6773
/// # }
68-
/// use volatile::access::{ReadOnly, ReadWrite};
74+
/// use volatile::access::{ReadOnly, ReadWrite, RestrictAccess};
6975
/// use volatile::{map_field, VolatilePtr};
7076
///
71-
/// pub trait DeviceConfigVolatileFieldAccess<'a> {
72-
/// fn feature_select(self) -> VolatilePtr<'a, u32, ReadWrite>;
77+
/// pub trait DeviceConfigVolatileFieldAccess<'a, A> {
78+
/// fn feature_select(self) -> VolatilePtr<'a, u32, A::Restricted>
79+
/// where
80+
/// A: RestrictAccess<ReadWrite>;
7381
///
74-
/// fn feature(self) -> VolatilePtr<'a, u32, ReadOnly>;
82+
/// fn feature(self) -> VolatilePtr<'a, u32, A::Restricted>
83+
/// where
84+
/// A: RestrictAccess<ReadOnly>;
7585
/// }
7686
///
77-
/// impl<'a> DeviceConfigVolatileFieldAccess<'a> for VolatilePtr<'a, DeviceConfig, ReadWrite> {
78-
/// fn feature_select(self) -> VolatilePtr<'a, u32, ReadWrite> {
87+
/// impl<'a, A> DeviceConfigVolatileFieldAccess<'a, A> for VolatilePtr<'a, DeviceConfig, A> {
88+
/// fn feature_select(self) -> VolatilePtr<'a, u32, A::Restricted>
89+
/// where
90+
/// A: RestrictAccess<ReadWrite>
91+
/// {
7992
/// map_field!(self.feature_select).restrict()
8093
/// }
8194
///
82-
/// fn feature(self) -> VolatilePtr<'a, u32, ReadOnly> {
95+
/// fn feature(self) -> VolatilePtr<'a, u32, A::Restricted>
96+
/// where
97+
/// A: RestrictAccess<ReadOnly>
98+
/// {
8399
/// map_field!(self.feature).restrict()
84100
/// }
85101
/// }

volatile-macro/src/volatile.rs

+25-12
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ fn parse_input(input: &ItemStruct) -> Result<ParsedInput> {
8484
}
8585

8686
let sig = parse_quote! {
87-
fn #ident(self) -> ::volatile::VolatilePtr<'a, #ty, #access>
87+
fn #ident(self) -> ::volatile::VolatilePtr<'a, #ty, A::Restricted>
88+
where
89+
A: ::volatile::access::RestrictAccess<#access>
8890
};
8991
sigs.push(sig);
9092
}
@@ -112,7 +114,7 @@ fn emit_trait(
112114
parse_quote! {
113115
#(#attrs)*
114116
#[allow(non_camel_case_types)]
115-
#vis trait #trait_ident <'a> {
117+
#vis trait #trait_ident <'a, A> {
116118
#(
117119
#(#method_attrs)*
118120
#sigs;
@@ -133,9 +135,10 @@ fn emit_impl(
133135

134136
parse_quote! {
135137
#[automatically_derived]
136-
impl<'a> #trait_ident<'a> for ::volatile::VolatilePtr<'a, #struct_ident, ::volatile::access::ReadWrite> {
138+
impl<'a, A> #trait_ident<'a, A> for ::volatile::VolatilePtr<'a, #struct_ident, A> {
137139
#(
138-
#sigs {
140+
#sigs,
141+
{
139142
::volatile::map_field!(self.#fields).restrict()
140143
}
141144
)*
@@ -183,24 +186,34 @@ mod tests {
183186
///
184187
/// This is a wonderful struct.
185188
#[allow(non_camel_case_types)]
186-
pub trait DeviceConfigVolatileFieldAccess<'a> {
187-
fn feature_select(self) -> ::volatile::VolatilePtr<'a, u32, ::volatile::access::ReadWrite>;
189+
pub trait DeviceConfigVolatileFieldAccess<'a, A> {
190+
fn feature_select(self) -> ::volatile::VolatilePtr<'a, u32, A::Restricted>
191+
where
192+
A: ::volatile::access::RestrictAccess<::volatile::access::ReadWrite>;
188193

189194
/// Feature.
190195
///
191196
/// This is a good field.
192-
fn feature(self) -> ::volatile::VolatilePtr<'a, u32, ReadOnly>;
197+
fn feature(self) -> ::volatile::VolatilePtr<'a, u32, A::Restricted>
198+
where
199+
A: ::volatile::access::RestrictAccess<ReadOnly>;
193200
}
194201
};
195202

196203
let expected_impl = quote! {
197204
#[automatically_derived]
198-
impl<'a> DeviceConfigVolatileFieldAccess<'a> for ::volatile::VolatilePtr<'a, DeviceConfig, ::volatile::access::ReadWrite> {
199-
fn feature_select(self) -> ::volatile::VolatilePtr<'a, u32, ::volatile::access::ReadWrite> {
205+
impl<'a, A> DeviceConfigVolatileFieldAccess<'a, A> for ::volatile::VolatilePtr<'a, DeviceConfig, A> {
206+
fn feature_select(self) -> ::volatile::VolatilePtr<'a, u32, A::Restricted>
207+
where
208+
A: ::volatile::access::RestrictAccess<::volatile::access::ReadWrite>,
209+
{
200210
::volatile::map_field!(self.feature_select).restrict()
201211
}
202212

203-
fn feature(self) -> ::volatile::VolatilePtr<'a, u32, ReadOnly> {
213+
fn feature(self) -> ::volatile::VolatilePtr<'a, u32, A::Restricted>
214+
where
215+
A: ::volatile::access::RestrictAccess<ReadOnly>,
216+
{
204217
::volatile::map_field!(self.feature).restrict()
205218
}
206219
}
@@ -230,12 +243,12 @@ mod tests {
230243

231244
let expected_trait = quote! {
232245
#[allow(non_camel_case_types)]
233-
pub trait DeviceConfigVolatileFieldAccess<'a> {}
246+
pub trait DeviceConfigVolatileFieldAccess<'a, A> {}
234247
};
235248

236249
let expected_impl = quote! {
237250
#[automatically_derived]
238-
impl<'a> DeviceConfigVolatileFieldAccess<'a> for ::volatile::VolatilePtr<'a, DeviceConfig, ::volatile::access::ReadWrite> {}
251+
impl<'a, A> DeviceConfigVolatileFieldAccess<'a, A> for ::volatile::VolatilePtr<'a, DeviceConfig, A> {}
239252
};
240253

241254
assert_eq!(

0 commit comments

Comments
 (0)