mirror of
https://gitlab.cern.ch/wotsubo/endcap-sl-software-ri-generator.git
synced 2025-02-23 17:17:08 +09:00
new(codegen_register): add multiple custom value fields generator
This commit is contained in:
parent
30279dc2b3
commit
9728af3551
1 changed files with 87 additions and 1 deletions
|
@ -421,8 +421,15 @@ fn generate_multiple_field(
|
||||||
.map(|mask| util::parse_to_literal(&format!("0x{mask:x}")).unwrap())
|
.map(|mask| util::parse_to_literal(&format!("0x{mask:x}")).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
debug_assert_eq!(masks.len(), num_multiple.try_into().unwrap());
|
debug_assert_eq!(masks.len(), num_multiple.try_into().unwrap());
|
||||||
|
let value_const_enumdefs = match single_field_type {
|
||||||
|
FieldType::RustType(_) => quote! {},
|
||||||
|
FieldType::CustomValue(values) => {
|
||||||
|
generate_custom_values_const_enumdef(&base_type, &snake_case_name, values)
|
||||||
|
}
|
||||||
|
};
|
||||||
let code_mask = quote! {
|
let code_mask = quote! {
|
||||||
const #mask_name: [#base_type; #id_num_multiple] = [#(#masks),*];
|
const #mask_name: [#base_type; #id_num_multiple] = [#(#masks),*];
|
||||||
|
#value_const_enumdefs
|
||||||
};
|
};
|
||||||
|
|
||||||
let (code_getter, code_setter) = match single_field_type {
|
let (code_getter, code_setter) = match single_field_type {
|
||||||
|
@ -438,7 +445,13 @@ fn generate_multiple_field(
|
||||||
masks,
|
masks,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
FieldType::CustomValue(_) => todo!("HERE NEXT"),
|
FieldType::CustomValue(values) => generate_multiple_custom_values_field(
|
||||||
|
mask_name,
|
||||||
|
base_type,
|
||||||
|
snake_case_name,
|
||||||
|
masks,
|
||||||
|
values,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
(code_mask, code_getter, code_setter)
|
(code_mask, code_getter, code_setter)
|
||||||
|
@ -528,3 +541,76 @@ fn generate_multiple_ux_field(
|
||||||
|
|
||||||
(code_getter, code_setter)
|
(code_getter, code_setter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_multiple_custom_values_field(
|
||||||
|
mask_name: Ident,
|
||||||
|
base_type: Ident,
|
||||||
|
snake_case_name: Ident,
|
||||||
|
masks: Vec<Literal>,
|
||||||
|
values: &[Value],
|
||||||
|
) -> (TokenStream, TokenStream) {
|
||||||
|
let value_enum_name =
|
||||||
|
util::parse_to_ident(&snake_case_name.to_string().to_upper_camel_case()).unwrap();
|
||||||
|
let num_multiple = masks.len();
|
||||||
|
let (getter_match_arms, setter_match_arms): (Vec<_>, Vec<_>) = values
|
||||||
|
.iter()
|
||||||
|
.map(|value| {
|
||||||
|
let const_name = custom_value_const_name(&snake_case_name, &value.name);
|
||||||
|
let variant_name = util::parse_to_ident(&value.name.to_upper_camel_case()).unwrap();
|
||||||
|
(
|
||||||
|
quote! {
|
||||||
|
#const_name => #value_enum_name::#variant_name
|
||||||
|
},
|
||||||
|
quote! {
|
||||||
|
#value_enum_name::#variant_name => #const_name
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unzip();
|
||||||
|
|
||||||
|
let elem_getter = masks.iter().enumerate().map(|(i, _mask)| {
|
||||||
|
quote! {
|
||||||
|
match ((self.inner & #mask_name[#i]))
|
||||||
|
>> (#mask_name[#i].trailing_zeros())
|
||||||
|
{
|
||||||
|
#(#getter_match_arms),*,
|
||||||
|
_ => panic!("must not reachable"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let code_getter = quote! {
|
||||||
|
pub fn #snake_case_name(&self) -> [#value_enum_name; #num_multiple] {
|
||||||
|
[
|
||||||
|
#(#elem_getter),*
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let setter_name = util::parse_to_ident(&format!("set_{}", snake_case_name)).unwrap();
|
||||||
|
let elem_setter = masks.iter().enumerate().map(|(i, _mask)| {
|
||||||
|
quote! {
|
||||||
|
match val[#i] {
|
||||||
|
#(#setter_match_arms),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let code_setter = quote! {
|
||||||
|
pub fn #setter_name(&self, val: [#value_enum_name; #num_multiple]) -> Self {
|
||||||
|
let val: [#base_type; #num_multiple] = [
|
||||||
|
#(#elem_setter),*
|
||||||
|
];
|
||||||
|
let mask: #base_type = #mask_name.iter().sum();
|
||||||
|
let update: #base_type = #mask_name
|
||||||
|
.iter()
|
||||||
|
.zip(val)
|
||||||
|
.map(|(mask, val)| (#base_type::from(val)) << (mask.trailing_zeros()))
|
||||||
|
.sum();
|
||||||
|
let mut inner = self.inner;
|
||||||
|
inner &= !mask;
|
||||||
|
inner |= update;
|
||||||
|
Self { inner }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(code_getter, code_setter)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue