Skip to content

Commit fbf0750

Browse files
bors[bot]couchand
andauthored
Merge #465
465: Accessor newtypes r=therealprof a=couchand Part 2 of #463, builds on #464. - Wraps register reader/writer and field readers in newtype wrappers, which significantly improves the documentation output. Again there's some minor potential for breaking changes: - If users named the complete type of the previous type alias, it would break. It seems more likely that they would use the alias, which will silently upgrade to a reference to the newtype. r? @burrbull Co-authored-by: Andrew Dona-Couch <[email protected]>
2 parents 48d4e20 + 02226ad commit fbf0750

File tree

2 files changed

+125
-28
lines changed

2 files changed

+125
-28
lines changed

src/generate/generic.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ pub trait RegisterSpec {
99
/// Trait implemented by readable registers to enable the `read` method.
1010
///
1111
/// Registers marked with `Writable` can be also `modify`'ed.
12-
pub trait Readable: RegisterSpec {}
12+
pub trait Readable: RegisterSpec {
13+
/// Result from a call to `read` and argument to `modify`.
14+
type Reader: core::convert::From<R<Self>> + core::ops::Deref<Target = R<Self>>;
15+
}
1316

1417
/// Trait implemented by writeable registers.
1518
///
1619
/// This enables the `write`, `write_with_zero` and `reset` methods.
1720
///
1821
/// Registers marked with `Readable` can be also `modify`'ed.
19-
pub trait Writable: RegisterSpec {}
22+
pub trait Writable: RegisterSpec {
23+
/// Writer type argument to `write`, et al.
24+
type Writer: core::convert::From<W<Self>> + core::ops::Deref<Target = W<Self>>;
25+
}
2026

2127
/// Reset value of the register.
2228
///
@@ -61,11 +67,11 @@ impl<REG: Readable> Reg<REG> {
6167
/// let flag = reader.field2().bit_is_set();
6268
/// ```
6369
#[inline(always)]
64-
pub fn read(&self) -> R<REG> {
65-
R {
70+
pub fn read(&self) -> REG::Reader {
71+
REG::Reader::from(R {
6672
bits: self.register.get(),
6773
_reg: marker::PhantomData,
68-
}
74+
})
6975
}
7076
}
7177

@@ -96,13 +102,13 @@ impl<REG: Resettable + Writable> Reg<REG> {
96102
#[inline(always)]
97103
pub fn write<F>(&self, f: F)
98104
where
99-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
105+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
100106
{
101107
self.register.set(
102-
f(&mut W {
108+
f(&mut REG::Writer::from(W {
103109
bits: REG::reset_value(),
104110
_reg: marker::PhantomData,
105-
})
111+
}))
106112
.bits,
107113
);
108114
}
@@ -118,13 +124,13 @@ where
118124
#[inline(always)]
119125
pub fn write_with_zero<F>(&self, f: F)
120126
where
121-
F: FnOnce(&mut W<REG>) -> &mut W<REG>,
127+
F: FnOnce(&mut REG::Writer) -> &mut REG::Writer,
122128
{
123129
self.register.set(
124-
f(&mut W {
130+
(*f(&mut REG::Writer::from(W {
125131
bits: REG::Ux::default(),
126132
_reg: marker::PhantomData,
127-
})
133+
})))
128134
.bits,
129135
);
130136
}
@@ -151,19 +157,19 @@ impl<REG: Readable + Writable> Reg<REG> {
151157
#[inline(always)]
152158
pub fn modify<F>(&self, f: F)
153159
where
154-
for<'w> F: FnOnce(&R<REG>, &'w mut W<REG>) -> &'w mut W<REG>,
160+
for<'w> F: FnOnce(&REG::Reader, &'w mut REG::Writer) -> &'w mut REG::Writer,
155161
{
156162
let bits = self.register.get();
157163
self.register.set(
158164
f(
159-
&R {
165+
&REG::Reader::from(R {
160166
bits,
161167
_reg: marker::PhantomData,
162-
},
163-
&mut W {
168+
}),
169+
&mut REG::Writer::from(W {
164170
bits,
165171
_reg: marker::PhantomData,
166-
},
172+
}),
167173
)
168174
.bits,
169175
);
@@ -174,7 +180,7 @@ impl<REG: Readable + Writable> Reg<REG> {
174180
///
175181
/// Result of the `read` methods of registers. Also used as a closure argument in the `modify`
176182
/// method.
177-
pub struct R<REG: RegisterSpec> {
183+
pub struct R<REG: RegisterSpec + ?Sized> {
178184
pub(crate) bits: REG::Ux,
179185
_reg: marker::PhantomData<REG>,
180186
}
@@ -201,7 +207,7 @@ where
201207
/// Register writer.
202208
///
203209
/// Used as an argument to the closures in the `write` and `modify` methods of the register.
204-
pub struct W<REG: RegisterSpec> {
210+
pub struct W<REG: RegisterSpec + ?Sized> {
205211
///Writable bits
206212
pub(crate) bits: REG::Ux,
207213
_reg: marker::PhantomData<REG>,
@@ -210,9 +216,8 @@ pub struct W<REG: RegisterSpec> {
210216
impl<REG: RegisterSpec> W<REG> {
211217
/// Writes raw bits to the register.
212218
#[inline(always)]
213-
pub unsafe fn bits(&mut self, bits: REG::Ux) -> &mut Self {
219+
pub unsafe fn bits(&mut self, bits: REG::Ux) {
214220
self.bits = bits;
215-
self
216221
}
217222
}
218223

src/generate/register.rs

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,22 @@ pub fn render(
5757
let desc = format!("Reader of register {}", register.name);
5858
mod_items.extend(quote! {
5959
#[doc = #desc]
60-
pub type R = crate::R<#name_uc_spec>;
60+
pub struct R(crate::R<#name_uc_spec>);
61+
62+
impl core::ops::Deref for R {
63+
type Target = crate::R<#name_uc_spec>;
64+
65+
#[inline(always)]
66+
fn deref(&self) -> &Self::Target {
67+
&self.0
68+
}
69+
}
70+
71+
impl core::convert::From<crate::R<#name_uc_spec>> for R {
72+
fn from(reader: crate::R<#name_uc_spec>) -> Self {
73+
R(reader)
74+
}
75+
}
6176
});
6277
methods.push("read");
6378
}
@@ -66,7 +81,29 @@ pub fn render(
6681
let desc = format!("Writer for register {}", register.name);
6782
mod_items.extend(quote! {
6883
#[doc = #desc]
69-
pub type W = crate::W<#name_uc_spec>;
84+
pub struct W(crate::W<#name_uc_spec>);
85+
86+
impl core::ops::Deref for W {
87+
type Target = crate::W<#name_uc_spec>;
88+
89+
#[inline(always)]
90+
fn deref(&self) -> &Self::Target {
91+
&self.0
92+
}
93+
}
94+
95+
impl core::ops::DerefMut for W {
96+
#[inline(always)]
97+
fn deref_mut(&mut self) -> &mut Self::Target {
98+
&mut self.0
99+
}
100+
}
101+
102+
impl core::convert::From<crate::W<#name_uc_spec>> for W {
103+
fn from(writer: crate::W<#name_uc_spec>) -> Self {
104+
W(writer)
105+
}
106+
}
70107
});
71108
methods.push("write_with_zero");
72109
if can_reset {
@@ -125,6 +162,14 @@ pub fn render(
125162

126163
mod_items.extend(w_impl_items);
127164

165+
mod_items.extend(quote! {
166+
#[doc = "Writes raw bits to the register."]
167+
pub unsafe fn bits(&mut self, bits: #rty) -> &mut Self {
168+
self.0.bits(bits);
169+
self
170+
}
171+
});
172+
128173
close.to_tokens(&mut mod_items);
129174
}
130175

@@ -167,7 +212,9 @@ pub fn render(
167212
);
168213
mod_items.extend(quote! {
169214
#[doc = #doc]
170-
impl crate::Readable for #name_uc_spec {}
215+
impl crate::Readable for #name_uc_spec {
216+
type Reader = R;
217+
}
171218
});
172219
}
173220
if can_write {
@@ -177,7 +224,9 @@ pub fn render(
177224
);
178225
mod_items.extend(quote! {
179226
#[doc = #doc]
180-
impl crate::Writable for #name_uc_spec {}
227+
impl crate::Writable for #name_uc_spec {
228+
type Writer = W;
229+
}
181230
});
182231
}
183232
if let Some(rv) = res_val.map(util::hex) {
@@ -388,7 +437,22 @@ pub fn fields(
388437

389438
mod_items.extend(quote! {
390439
#[doc = #readerdoc]
391-
pub type #name_pc_r = crate::FieldReader<#fty, #name_pc_a>;
440+
pub struct #name_pc_r(crate::FieldReader<#fty, #name_pc_a>);
441+
442+
impl #name_pc_r {
443+
pub(crate) fn new(bits: #fty) -> Self {
444+
#name_pc_r(crate::FieldReader::new(bits))
445+
}
446+
}
447+
448+
impl core::ops::Deref for #name_pc_r {
449+
type Target = crate::FieldReader<#fty, #name_pc_a>;
450+
451+
#[inline(always)]
452+
fn deref(&self) -> &Self::Target {
453+
&self.0
454+
}
455+
}
392456
});
393457
} else {
394458
let has_reserved_variant = evs.values.len() != (1 << width);
@@ -463,23 +527,51 @@ pub fn fields(
463527
#[doc = #doc]
464528
#inline
465529
pub fn #is_variant(&self) -> bool {
466-
*self == #name_pc_a::#pc
530+
**self == #name_pc_a::#pc
467531
}
468532
});
469533
}
470534

471535
mod_items.extend(quote! {
472536
#[doc = #readerdoc]
473-
pub type #name_pc_r = crate::FieldReader<#fty, #name_pc_a>;
537+
pub struct #name_pc_r(crate::FieldReader<#fty, #name_pc_a>);
538+
474539
impl #name_pc_r {
540+
pub(crate) fn new(bits: #fty) -> Self {
541+
#name_pc_r(crate::FieldReader::new(bits))
542+
}
475543
#enum_items
476544
}
545+
546+
impl core::ops::Deref for #name_pc_r {
547+
type Target = crate::FieldReader<#fty, #name_pc_a>;
548+
549+
#[inline(always)]
550+
fn deref(&self) -> &Self::Target {
551+
&self.0
552+
}
553+
}
477554
});
478555
}
479556
} else {
480557
mod_items.extend(quote! {
481558
#[doc = #readerdoc]
482-
pub type #name_pc_r = crate::FieldReader<#fty, #fty>;
559+
pub struct #name_pc_r(crate::FieldReader<#fty, #fty>);
560+
561+
impl #name_pc_r {
562+
pub(crate) fn new(bits: #fty) -> Self {
563+
#name_pc_r(crate::FieldReader::new(bits))
564+
}
565+
}
566+
567+
impl core::ops::Deref for #name_pc_r {
568+
type Target = crate::FieldReader<#fty, #fty>;
569+
570+
#[inline(always)]
571+
fn deref(&self) -> &Self::Target {
572+
&self.0
573+
}
574+
}
483575
})
484576
}
485577
}

0 commit comments

Comments
 (0)