diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a8f44f..878d2f1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] +- Refactor `Accessor` + ## [v0.33.3] - 2024-05-10 - Yet more clean field & register `Debug` diff --git a/src/generate/peripheral.rs b/src/generate/peripheral.rs index 382b3436..f7ea1520 100644 --- a/src/generate/peripheral.rs +++ b/src/generate/peripheral.rs @@ -294,7 +294,7 @@ struct RegisterBlockField { syn_field: syn::Field, offset: u32, size: u32, - accessors: Vec, + accessors: Vec, } #[derive(Clone, Debug)] @@ -1003,17 +1003,18 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result { @@ -1059,28 +1060,18 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result::with_capacity((array_info.dim + 1) as _); - accessors.push(if array_convertible { - ArrayAccessor { - doc, - name: accessor_name.clone(), - ty: ty.clone(), - offset: unsuffixed(info.address_offset), - dim: unsuffixed(array_info.dim), - increment: unsuffixed(array_info.dim_increment), - } - .into() - } else { - RawArrayAccessor { + let mut accessors = Vec::with_capacity((array_info.dim + 1) as _); + accessors.push( + Accessor::Array(ArrayAccessor { doc, name: accessor_name.clone(), ty: ty.clone(), offset: unsuffixed(info.address_offset), dim: unsuffixed(array_info.dim), increment: unsuffixed(array_info.dim_increment), - } - .into() - }); + }) + .raw_if(!array_convertible), + ); if !sequential_indexes_from0 || !ends_with_index { for (i, ci) in svd::cluster::expand(info, array_info).enumerate() { let idx_name = ident(&ci.name, config, "cluster_accessor", span); @@ -1091,14 +1082,14 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result Result { @@ -1250,28 +1243,18 @@ fn expand_register( info.address_offset, &description, ); - let mut accessors = Vec::::with_capacity((array_info.dim + 1) as _); - accessors.push(if array_convertible { - ArrayAccessor { - doc, - name: accessor_name.clone(), - ty: ty.clone(), - offset: unsuffixed(info.address_offset), - dim: unsuffixed(array_info.dim), - increment: unsuffixed(array_info.dim_increment), - } - .into() - } else { - RawArrayAccessor { + let mut accessors = Vec::with_capacity((array_info.dim + 1) as _); + accessors.push( + Accessor::Array(ArrayAccessor { doc, name: accessor_name.clone(), ty: ty.clone(), offset: unsuffixed(info.address_offset), dim: unsuffixed(array_info.dim), increment: unsuffixed(array_info.dim_increment), - } - .into() - }); + }) + .raw_if(!array_convertible), + ); if !sequential_indexes_from0 || !ends_with_index { for (i, ri) in svd::register::expand(info, array_info).enumerate() { let idx_name = ident( @@ -1287,14 +1270,14 @@ fn expand_register( ); let i = unsuffixed(i as u64); accessors.push( - ArrayElemAccessor { + Accessor::ArrayElem(ArrayElemAccessor { doc, name: idx_name, ty: ty.clone(), basename: accessor_name.clone(), i, - } - .into(), + }) + .raw_if(false), ); } }; @@ -1324,17 +1307,18 @@ fn expand_register( let name = ident(&ri.name, config, "register_accessor", span); let syn_field = new_syn_field(name.clone(), ty.clone()); + let accessor = Accessor::Reg(RegAccessor { + doc, + name, + ty: ty.clone(), + offset: unsuffixed(info.address_offset), + }) + .raw_if(false); register_expanded.push(RegisterBlockField { syn_field, offset: ri.address_offset, size: register_size, - accessors: vec![RegAccessor { - doc, - name, - ty: ty.clone(), - offset: unsuffixed(info.address_offset), - } - .into()], + accessors: vec![accessor], }); } } diff --git a/src/generate/peripheral/accessor.rs b/src/generate/peripheral/accessor.rs index d074117b..d30576c0 100644 --- a/src/generate/peripheral/accessor.rs +++ b/src/generate/peripheral/accessor.rs @@ -4,121 +4,118 @@ use quote::{quote, ToTokens}; #[derive(Clone, Debug)] pub enum Accessor { Reg(RegAccessor), - RawReg(RawRegAccessor), Array(ArrayAccessor), - RawArray(RawArrayAccessor), ArrayElem(ArrayElemAccessor), } +#[derive(Clone, Debug)] +pub enum AccessType { + Ref(Accessor), + RawRef(Accessor), +} + impl Accessor { - pub fn raw(self) -> Self { - match self { - Self::RawReg(_) | Self::RawArray(_) | Self::ArrayElem(_) => self, - Self::Reg(a) => RawRegAccessor { - doc: a.doc, - name: a.name, - ty: a.ty, - offset: a.offset, - } - .into(), - Self::Array(a) => RawArrayAccessor { - doc: a.doc, - name: a.name, - ty: a.ty, - offset: a.offset, - dim: a.dim, - increment: a.increment, - } - .into(), + pub fn raw_if(self, flag: bool) -> AccessType { + if flag { + AccessType::RawRef(self) + } else { + AccessType::Ref(self) } } } -impl ToTokens for Accessor { - fn to_tokens(&self, tokens: &mut TokenStream) { +impl AccessType { + pub fn raw(self) -> Self { match self { - Self::Reg(a) => a.to_tokens(tokens), - Self::RawReg(a) => a.to_tokens(tokens), - Self::Array(a) => a.to_tokens(tokens), - Self::RawArray(a) => a.to_tokens(tokens), - Self::ArrayElem(a) => a.to_tokens(tokens), + Self::RawRef(_) => self, + Self::Ref(a) => Self::RawRef(a), } } } -impl From for Accessor { - fn from(value: RegAccessor) -> Self { - Self::Reg(value) - } -} - -impl From for Accessor { - fn from(value: RawRegAccessor) -> Self { - Self::RawReg(value) - } -} - -impl From for Accessor { - fn from(value: ArrayAccessor) -> Self { - Self::Array(value) - } -} - -impl From for Accessor { - fn from(value: RawArrayAccessor) -> Self { - Self::RawArray(value) - } -} - -impl From for Accessor { - fn from(value: ArrayElemAccessor) -> Self { - Self::ArrayElem(value) - } -} - -#[derive(Clone, Debug)] -pub struct RegAccessor { - pub doc: String, - pub name: Ident, - pub ty: syn::Type, - pub offset: syn::LitInt, -} - -impl ToTokens for RegAccessor { +impl ToTokens for AccessType { fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { doc, name, ty, .. } = self; - quote! { - #[doc = #doc] - #[inline(always)] - pub const fn #name(&self) -> &#ty { - &self.#name + match self { + Self::Ref(Accessor::Reg(RegAccessor { doc, name, ty, .. })) => { + quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #name(&self) -> &#ty { + &self.#name + } + } } - } - .to_tokens(tokens); - } -} - -#[derive(Clone, Debug)] -pub struct RawRegAccessor { - pub doc: String, - pub name: Ident, - pub ty: syn::Type, - pub offset: syn::LitInt, -} - -impl ToTokens for RawRegAccessor { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { - doc, - name, - ty, - offset, - } = self; - quote! { - #[doc = #doc] - #[inline(always)] - pub const fn #name(&self) -> &#ty { - unsafe { &*(self as *const Self).cast::().add(#offset).cast() } + Self::RawRef(Accessor::Reg(RegAccessor { + doc, + name, + ty, + offset, + })) => { + quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #name(&self) -> &#ty { + unsafe { &*(self as *const Self).cast::().add(#offset).cast() } + } + } + } + Self::Ref(Accessor::Array(ArrayAccessor { doc, name, ty, .. })) => { + let name_iter = Ident::new(&format!("{name}_iter"), Span::call_site()); + quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #name(&self, n: usize) -> &#ty { + &self.#name[n] + } + #[doc = "Iterator for array of:"] + #[doc = #doc] + #[inline(always)] + pub fn #name_iter(&self) -> impl Iterator { + self.#name.iter() + } + } + } + Self::RawRef(Accessor::Array(ArrayAccessor { + doc, + name, + ty, + offset, + dim, + increment, + })) => { + let name_iter = Ident::new(&format!("{name}_iter"), Span::call_site()); + let cast = quote! { unsafe { &*(self as *const Self).cast::().add(#offset).add(#increment * n).cast() } }; + quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #name(&self, n: usize) -> &#ty { + #[allow(clippy::no_effect)] + [(); #dim][n]; + #cast + } + #[doc = "Iterator for array of:"] + #[doc = #doc] + #[inline(always)] + pub fn #name_iter(&self) -> impl Iterator { + (0..#dim).map(move |n| #cast) + } + } + } + Self::RawRef(Accessor::ArrayElem(elem)) | Self::Ref(Accessor::ArrayElem(elem)) => { + let ArrayElemAccessor { + doc, + name, + ty, + basename, + i, + } = elem; + quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #name(&self) -> &#ty { + self.#basename(#i) + } + } } } .to_tokens(tokens); @@ -126,38 +123,15 @@ impl ToTokens for RawRegAccessor { } #[derive(Clone, Debug)] -pub struct ArrayAccessor { +pub struct RegAccessor { pub doc: String, pub name: Ident, pub ty: syn::Type, pub offset: syn::LitInt, - pub dim: syn::LitInt, - pub increment: syn::LitInt, -} - -impl ToTokens for ArrayAccessor { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { doc, name, ty, .. } = self; - let name_iter = Ident::new(&format!("{name}_iter"), Span::call_site()); - quote! { - #[doc = #doc] - #[inline(always)] - pub const fn #name(&self, n: usize) -> &#ty { - &self.#name[n] - } - #[doc = "Iterator for array of:"] - #[doc = #doc] - #[inline(always)] - pub fn #name_iter(&self) -> impl Iterator { - self.#name.iter() - } - } - .to_tokens(tokens); - } } #[derive(Clone, Debug)] -pub struct RawArrayAccessor { +pub struct ArrayAccessor { pub doc: String, pub name: Ident, pub ty: syn::Type, @@ -166,37 +140,6 @@ pub struct RawArrayAccessor { pub increment: syn::LitInt, } -impl ToTokens for RawArrayAccessor { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { - doc, - name, - ty, - offset, - dim, - increment, - } = self; - let name_iter = Ident::new(&format!("{name}_iter"), Span::call_site()); - let cast = quote! { unsafe { &*(self as *const Self).cast::().add(#offset).add(#increment * n).cast() } }; - quote! { - #[doc = #doc] - #[inline(always)] - pub const fn #name(&self, n: usize) -> &#ty { - #[allow(clippy::no_effect)] - [(); #dim][n]; - #cast - } - #[doc = "Iterator for array of:"] - #[doc = #doc] - #[inline(always)] - pub fn #name_iter(&self) -> impl Iterator { - (0..#dim).map(move |n| #cast) - } - } - .to_tokens(tokens); - } -} - #[derive(Clone, Debug)] pub struct ArrayElemAccessor { pub doc: String, @@ -205,23 +148,3 @@ pub struct ArrayElemAccessor { pub basename: Ident, pub i: syn::LitInt, } - -impl ToTokens for ArrayElemAccessor { - fn to_tokens(&self, tokens: &mut TokenStream) { - let Self { - doc, - name, - ty, - basename, - i, - } = &self; - quote! { - #[doc = #doc] - #[inline(always)] - pub const fn #name(&self) -> &#ty { - self.#basename(#i) - } - } - .to_tokens(tokens); - } -}