update(generator): use u8 and u16 for register value when possible

Use `u8` and `u16` if the register has mask `0xff` or `0xffff`.
As noted in `reg_type_def_masked`, `bool` cannot be used as `T` here
This commit is contained in:
Wataru Otsubo 2025-06-01 03:47:04 +09:00
parent 5ef9387d33
commit 1511408eba
2 changed files with 40 additions and 16 deletions

View file

@ -82,6 +82,21 @@ mod util {
} }
} }
/// Derive appropriate rust type for right aligned `mask`ed value.
pub(super) fn from_exact_mask(mask: u32) -> Option<RustUxTypes> {
if mask.trailing_zeros() != 0 {
return None;
}
match 32 - mask.leading_zeros() {
0 => panic!("mask cannot be 0"),
1 => Some(RustUxTypes::Bool),
8 => Some(RustUxTypes::U8),
16 => Some(RustUxTypes::U16),
32 => Some(RustUxTypes::U32),
_ => None,
}
}
pub(super) fn to_rust_type_token(&self) -> proc_macro2::Ident { pub(super) fn to_rust_type_token(&self) -> proc_macro2::Ident {
match self { match self {
RustUxTypes::Bool => parse_to_ident("bool").unwrap(), RustUxTypes::Bool => parse_to_ident("bool").unwrap(),

View file

@ -71,26 +71,35 @@ fn reg_type_def_masked(
let x: RustUxTypes = basetype.into(); let x: RustUxTypes = basetype.into();
x.to_rust_type_token() x.to_rust_type_token()
}; };
let type_t = RustUxTypes::from_exact_mask(mask);
let out = quote! { // u8, u16 already implements Into and TryFrom with u32
#[derive(Debug, Clone, Copy, Default)] // but bool doen't implement TryFrom<u32>, so it cannot be used as `T` here
pub struct #upper_camel_name(pub #type_ux); match type_t {
impl TryFrom<#type_ux> for #upper_camel_name { None | Some(RustUxTypes::Bool) => {
type Error = crate::register_spec::DataConversionError<#type_ux, Self>; let out = quote! {
#[derive(Debug, Clone, Copy, Default)]
pub struct #upper_camel_name(pub #type_ux);
impl TryFrom<#type_ux> for #upper_camel_name {
type Error = crate::register_spec::DataConversionError<#type_ux, Self>;
fn try_from(value: #type_ux) -> Result<Self, Self::Error> { fn try_from(value: #type_ux) -> Result<Self, Self::Error> {
Ok(Self(value & #mask)) Ok(Self(value & #mask))
} }
}
impl From<#upper_camel_name> for #type_ux {
fn from(value: #upper_camel_name) -> Self {
value.0
}
}
};
(out, upper_camel_name.clone(), type_ux)
} }
impl From<#upper_camel_name> for #type_ux { Some(type_t) => {
fn from(value: #upper_camel_name) -> Self { let out = quote! {};
value.0 (out, type_t.to_rust_type_token(), type_ux)
}
} }
}
};
(out, upper_camel_name.clone(), type_ux)
} }
/// Where `T` has fields. /// Where `T` has fields.