Skip to content

Commit db74cb8

Browse files
author
Jorge Aparicio
committed
make the enumeratedValues-less API just like the enumeratedValues-based one
1 parent ccf6dd1 commit db74cb8

File tree

1 file changed

+113
-135
lines changed

1 file changed

+113
-135
lines changed

src/lib.rs

Lines changed: 113 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -581,65 +581,93 @@ pub fn gen_register(r: &Register,
581581
_ => unreachable!(),
582582
}
583583

584-
if let Some(ref fields) = r.fields {
585-
let mut reexported = HashSet::new();
586-
let mut mod_items = vec![];
587-
let mut impl_items = vec![];
588-
589-
if access == Access::ReadWrite {
590-
impl_items.push(quote! {
591-
pub fn modify<F>(&mut self, f: F)
592-
where for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W,
593-
{
594-
let bits = self.register.read();
595-
let r = R { bits: bits };
596-
let mut w = W { bits: bits };
597-
f(&r, &mut w);
598-
self.register.write(w.bits);
599-
}
600-
});
601-
}
584+
let mut mod_items = vec![];
585+
let mut impl_items = vec![];
586+
let mut r_impl_items = vec![];
587+
let mut w_impl_items = vec![];
588+
if access == Access::ReadWrite {
589+
impl_items.push(quote! {
590+
pub fn modify<F>(&mut self, f: F)
591+
where for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W,
592+
{
593+
let bits = self.register.read();
594+
let r = R { bits: bits };
595+
let mut w = W { bits: bits };
596+
f(&r, &mut w);
597+
self.register.write(w.bits);
598+
}
599+
});
600+
}
602601

603-
if access == Access::ReadOnly || access == Access::ReadWrite {
604-
impl_items.push(quote! {
605-
pub fn read(&self) -> R {
606-
R { bits: self.register.read() }
607-
}
608-
});
609-
}
602+
if access == Access::ReadOnly || access == Access::ReadWrite {
603+
impl_items.push(quote! {
604+
pub fn read(&self) -> R {
605+
R { bits: self.register.read() }
606+
}
607+
});
610608

611-
if access == Access::WriteOnly || access == Access::ReadWrite {
612-
impl_items.push(quote! {
613-
pub fn write<F>(&mut self, f: F)
614-
where F: FnOnce(&mut W) -> &mut W,
615-
{
616-
let mut w = W::reset_value();
617-
f(&mut w);
618-
self.register.write(w.bits);
619-
}
620-
});
621-
}
609+
mod_items.push(quote! {
610+
pub struct R {
611+
bits: #reg_ty,
612+
}
613+
});
614+
615+
r_impl_items.push(quote! {
616+
pub fn bits(&self) -> #reg_ty {
617+
self.bits
618+
}
619+
});
620+
}
621+
622+
if access == Access::WriteOnly || access == Access::ReadWrite {
623+
impl_items.push(quote! {
624+
pub fn write<F>(&mut self, f: F)
625+
where F: FnOnce(&mut W) -> &mut W,
626+
{
627+
let mut w = W::reset_value();
628+
f(&mut w);
629+
self.register.write(w.bits);
630+
}
631+
});
622632

623633
mod_items.push(quote! {
624-
impl super::#name_pc {
625-
#(#impl_items)*
634+
pub struct W {
635+
bits: #reg_ty,
626636
}
627637
});
628638

629-
if access == Access::ReadOnly || access == Access::ReadWrite {
630-
mod_items.push(quote! {
631-
pub struct R {
632-
bits: #reg_ty,
639+
if let Some(reset_value) =
640+
r.reset_value
641+
.or(d.reset_value)
642+
.map(|x| Lit::Int(x as u64, IntTy::Unsuffixed)) {
643+
w_impl_items.push(quote! {
644+
/// Reset value
645+
pub fn reset_value() -> W {
646+
W { bits: #reset_value }
633647
}
634648
});
649+
}
635650

636-
let mut impl_items = vec![];
637-
impl_items.push(quote! {
638-
pub fn bits(&self) -> #reg_ty {
639-
self.bits
640-
}
641-
});
651+
w_impl_items.push(quote! {
652+
pub unsafe fn bits(&mut self, bits: #reg_ty) -> &mut Self {
653+
self.bits = bits;
654+
self
655+
}
656+
});
657+
}
658+
659+
mod_items.push(quote! {
660+
impl super::#name_pc {
661+
#(#impl_items)*
662+
}
663+
});
664+
665+
let fields = r.fields.as_ref().map(|fs| &**fs).unwrap_or(&[]);
642666

667+
if !fields.is_empty() {
668+
let mut reexported = HashSet::new();
669+
670+
if access == Access::ReadOnly || access == Access::ReadWrite {
643671
for field in fields {
644672
let field_name = Ident::new(&*field.name
645673
.to_sanitized_snake_case());
@@ -652,7 +680,7 @@ pub fn gen_register(r: &Register,
652680
IntTy::Unsuffixed);
653681
let field_ty = width.to_ty();
654682

655-
impl_items.push(quote! {
683+
r_impl_items.push(quote! {
656684
fn #_field_name(&self) -> #field_ty {
657685
const MASK: #field_ty = #mask;
658686
const OFFSET: u8 = #offset;
@@ -721,7 +749,7 @@ pub fn gen_register(r: &Register,
721749
}
722750
}
723751

724-
impl_items.push(quote! {
752+
r_impl_items.push(quote! {
725753
pub fn #field_name(&self) -> #enum_name {
726754
#enum_name::_from(self.#_field_name())
727755
}
@@ -744,8 +772,8 @@ pub fn gen_register(r: &Register,
744772
let pc = &v.pc;
745773

746774
quote! {
747-
#enum_name::#pc => #value
748-
}
775+
#enum_name::#pc => #value
776+
}
749777
});
750778
enum_items.push(quote! {
751779
pub fn bits(&self) -> #field_ty {
@@ -761,8 +789,8 @@ pub fn gen_register(r: &Register,
761789
let pc = &v.pc;
762790

763791
quote! {
764-
#i => #enum_name::#pc
765-
}
792+
#i => #enum_name::#pc
793+
}
766794
});
767795

768796
enum_items.push(quote! {
@@ -780,14 +808,15 @@ pub fn gen_register(r: &Register,
780808
if let Some(ref sc) = v.sc {
781809
let pc = &v.pc;
782810

783-
let is_variant = Ident::new(&*format!("is_{}",
784-
sc));
811+
let is_variant = {
812+
Ident::new(&*format!("is_{}", sc))
813+
};
785814

786815
enum_items.push(quote! {
787816
pub fn #is_variant(&self) -> bool {
788817
*self == #enum_name::#pc
789818
}
790-
})
819+
});
791820
}
792821
}
793822

@@ -798,48 +827,16 @@ pub fn gen_register(r: &Register,
798827
});
799828
}
800829
} else {
801-
impl_items.push(quote! {
830+
r_impl_items.push(quote! {
802831
pub fn #field_name(&self) -> #field_ty {
803832
self.#_field_name()
804833
}
805834
});
806835
}
807836
}
808-
809-
mod_items.push(quote! {
810-
impl R {
811-
#(#impl_items)*
812-
}
813-
});
814837
}
815838

816839
if access == Access::WriteOnly || access == Access::ReadWrite {
817-
mod_items.push(quote! {
818-
pub struct W {
819-
bits: #reg_ty,
820-
}
821-
});
822-
823-
let mut impl_items = vec![];
824-
if let Some(reset_value) =
825-
r.reset_value
826-
.or(d.reset_value)
827-
.map(|x| Lit::Int(x as u64, IntTy::Unsuffixed)) {
828-
impl_items.push(quote! {
829-
/// Reset value
830-
pub fn reset_value() -> W {
831-
W { bits: #reset_value }
832-
}
833-
});
834-
}
835-
836-
impl_items.push(quote! {
837-
pub unsafe fn bits(&mut self, bits: #reg_ty) -> &mut Self {
838-
self.bits = bits;
839-
self
840-
}
841-
});
842-
843840
for field in fields {
844841
let field_name_sc = Ident::new(&*field.name
845842
.to_sanitized_snake_case());
@@ -849,7 +846,8 @@ pub fn gen_register(r: &Register,
849846
IntTy::Unsuffixed);
850847
let field_ty = width.to_ty();
851848
let proxy = Ident::new(&*format!("_{}W",
852-
field.name.to_pascal_case()));
849+
field.name
850+
.to_pascal_case()));
853851

854852
mod_items.push(quote! {
855853
/// Proxy
@@ -891,8 +889,8 @@ pub fn gen_register(r: &Register,
891889

892890
if !reexported.contains(&enum_name) {
893891
mod_items.push(quote! {
894-
pub use super::#register::#enum_name;
895-
});
892+
pub use super::#register::#enum_name;
893+
});
896894

897895
reexported.insert(enum_name.clone());
898896
}
@@ -914,9 +912,9 @@ pub fn gen_register(r: &Register,
914912
.collect::<Vec<_>>();
915913

916914
// Whether the `bits` method should be `unsafe`.
917-
// `bits` can be safe when enumeratedValues covers all the
918-
// possible values of the bitfield or, IOW, when there are
919-
// no reserved bit patterns.
915+
// `bits` can be safe when enumeratedValues covers all
916+
// the possible values of the bitfield or, IOW, when
917+
// there are no reserved bit patterns.
920918
bits_is_safe = variants.len() == 1 << width;
921919

922920
if base.is_none() {
@@ -952,14 +950,14 @@ pub fn gen_register(r: &Register,
952950
if bits_is_safe {
953951
proxy_items.push(quote! {
954952
pub fn variant(self,
955-
variant: #enum_name) -> &'a mut W {
953+
variant: #enum_name) -> &'a mut W {
956954
self.bits(variant._bits())
957955
}
958956
});
959957
} else {
960958
proxy_items.push(quote! {
961959
pub fn variant(self,
962-
variant: #enum_name) -> &'a mut W {
960+
variant: #enum_name) -> &'a mut W {
963961
unsafe {
964962
self.bits(variant._bits())
965963
}
@@ -1015,59 +1013,39 @@ pub fn gen_register(r: &Register,
10151013
}
10161014
});
10171015

1018-
impl_items.push(quote! {
1016+
w_impl_items.push(quote! {
10191017
pub fn #field_name_sc(&mut self) -> #proxy {
10201018
#proxy {
10211019
register: self,
10221020
}
10231021
}
10241022
});
10251023
}
1026-
1027-
mod_items.push(quote! {
1028-
impl W {
1029-
#(#impl_items)*
1030-
}
1031-
});
10321024
}
1025+
}
10331026

1034-
items.push(quote! {
1035-
pub mod #name_sc {
1036-
#(#mod_items)*
1027+
if access == Access::ReadOnly || access == Access::ReadWrite {
1028+
mod_items.push(quote! {
1029+
impl R {
1030+
#(#r_impl_items)*
10371031
}
10381032
});
1039-
} else {
1040-
let mut impl_items = vec![];
1041-
1042-
match access {
1043-
Access::ReadOnly | Access::ReadWrite => {
1044-
impl_items.push(quote! {
1045-
pub fn read(&self) -> #reg_ty {
1046-
self.register.read()
1047-
}
1048-
});
1049-
}
1050-
_ => {}
1051-
}
1052-
1053-
match access {
1054-
Access::ReadOnly | Access::ReadWrite => {
1055-
impl_items.push(quote! {
1056-
pub fn write(&mut self, value: #reg_ty) {
1057-
self.register.write(value);
1058-
}
1059-
});
1060-
}
1061-
_ => {}
1062-
}
1033+
}
10631034

1064-
items.push(quote! {
1065-
impl #name_pc {
1066-
#(#impl_items)*
1035+
if access == Access::WriteOnly || access == Access::ReadWrite {
1036+
mod_items.push(quote! {
1037+
impl W {
1038+
#(#w_impl_items)*
10671039
}
10681040
});
10691041
}
10701042

1043+
items.push(quote! {
1044+
pub mod #name_sc {
1045+
#(#mod_items)*
1046+
}
1047+
});
1048+
10711049
items
10721050
}
10731051

0 commit comments

Comments
 (0)