Generate enum-typed setters and constructors for signals with value descriptions#178
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
6fd246c to
fe3a365
Compare
| w, | ||
| "{visibility}fn set_{field}(&mut self, value: {typ}) -> Result<(), CanError> {{", | ||
| )?; | ||
| let param_ty = signal_pub_type(dbc, msg, signal); |
There was a problem hiding this comment.
(would prefer full name param_type or signal_type?)
| /// Set raw value of 'Value1' | ||
| #[inline(always)] | ||
| pub fn set_value1(&mut self, value: u8) -> Result<(), CanError> { | ||
| pub fn set_value1_raw(&mut self, value: u8) -> Result<(), CanError> { |
There was a problem hiding this comment.
I think signal bits extracted from received/sent bytes are called raw. This raw value is then converted into physical value (e.g. bits into floating voltage 5.02V) by scaling and adding offset.
This function is actually converting physical value into its raw value and we dont have any function to set the real raw bits. Not sure if there are usecases, but it might be little confusing? Not sure if set_value1_logical wouldn't be better?
The non-suffix type-safe set_value1 would pass logical value into set_value1_logical, that applies linear transformation and then stores the raw bits into the buffer.
There was a problem hiding this comment.
I agree that the CAN convention is that 'raw' values are unscaled. However, the existing getters value1() / value1_raw() both return the physical value, and value1() returns an enum if applicable instead of its primitive value. The change I'm proposing with the setters set_value1() / set_value1_raw() matches the existing logic used today.
I'm happy to use _logical() instead of _raw() everywhere but then we should apply it to both the getters and setters equally.
There was a problem hiding this comment.
or maybe _unchecked() instead of _logical()? So we can keep _raw() reserved for raw value just to be placed into the payload.
Do you have opinion @nyurik? As we are breaking the API, it would be good idea to do it once.
Otherwise I am happy with the changes.
There was a problem hiding this comment.
I'm OK with either _unchecked() or _logical() personally.
There was a problem hiding this comment.
Actually with some more thought, I think _unchecked() might give the wrong impression. The values are still checked and the functions are all safe. If we really want to reserve a name for future use we could do:
value1() → typed/decoded (enum)
value1_physical() → the scaled scalar (currently _raw())
value1_raw() or value1_bits() → unscaled payload integer (future)
I'm also OK to leave the naming changes to a separate PR if this needs to be discussed further, and just merge this one with the existing consistent naming for now.
There was a problem hiding this comment.
I've decided to just remove the set_value_raw()` functions entirely for now, so we should be able to merge these changes without affecting any other naming.
The last feature I planned to introduce into dbc-codegen is to add the raw integer getters and setters, so we can handle the names in that PR.
There was a problem hiding this comment.
The raw/bits functions could be useful at least internally for setting default signal values.
fe3a365 to
43b5de7
Compare
43b5de7 to
49c2d1a
Compare
new()constructors andset_<signal>()setters to accept enums for signals that have an associated enum type (value description in the DBC). This mirrors the existing enum-typed getters, making the getter and setter APIs symmetrical.This is a breaking change for DBCs that have signals with value descriptions, but should make these signals much cleaner to handle. The best approach is to directly pass the enum-typed value into
set_<signal>()andnew(). Raw or undescribed values can still be set through the enum's_Othervariant, e.g.set_<signal>(SignalEnum::_Other(value)).This PR should be stacked on top of #176.