technocreatives / dbc-codegen

Generate Rust structs for messages from a dbc (CAN bus definition) file.
Apache License 2.0
43 stars 22 forks source link

Fix signed offset integers where scaled int size equals raw size. #72

Closed projectgus closed 1 month ago

projectgus commented 1 month ago

For signals where a signed integer is generated using an offset, the generated code wouldn't compile if the raw unsigned value and the signed result fit in the same size.

For example, without this fix a signal such as this (included in this PR as new test case):

 SG_ WithOffset : 32|12@1+ (1,-1000) [-1000|3000] "" XXX

Generates this function:

    pub fn with_offset_raw(&self) -> i16 {
        let signal = self.raw.view_bits::<Lsb0>()[32..44].load_le::<u16>();

        let factor = 1;
        i16::from(signal)
            .saturating_mul(factor)
            .saturating_sub(1000)
    }

Which fails to compile, because u16 won't convert to i16 without a cast:

error[E0277]: the trait bound `i16: From<u16>` is not satisfied
   --> testing/can-messages/src/messages.rs:511:19
    |
511 |         i16::from(signal)
    |         --------- ^^^^^^ the trait `From<u16>` is not implemented for `i16`
    |         |
    |         required by a bound introduced by this call
    |
    = help: the following other types implement trait `From<T>`:
              <i16 as From<bool>>
              <i16 as From<i8>>
              <i16 as From<u8>>
              <i16 as From<NonZeroI16>>

This PR fixes the above, and also adds a test case for offset integers that take up a full Rust integer type (these already generated correctly.)