diff --git a/src/connection/mod.rs b/src/connection/mod.rs index c9acca6..12938fc 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -101,18 +101,31 @@ pub enum LogicalUnit { Three, } +impl LogicalUnit { + /// Construct a `LogicalUnit` from the two lowest bits of `value`, + /// ignoring all other bits. + pub fn from_low_bits(value: u8) -> Self { + let value = value & 0b11; + + match value { + 0b00 => Self::Zero, + 0b01 => Self::One, + 0b10 => Self::Two, + 0b11 => Self::Three, + _ => unreachable!("Value bitmasked with 0b11 has value greater than 3"), + } + } +} + impl TryFrom for LogicalUnit { type Error = (); fn try_from(value: u8) -> Result { - let val = match value { - 0 => Self::Zero, - 1 => Self::One, - 2 => Self::Two, - 3 => Self::Three, - _ => return Err(()), - }; - Ok(val) + if value <= 0b11 { + Ok(Self::from_low_bits(value)) + } else { + Err(()) + } } } diff --git a/src/storage/sdr/record/fru_device_locator.rs b/src/storage/sdr/record/fru_device_locator.rs index 89ea37f..f42625e 100644 --- a/src/storage/sdr/record/fru_device_locator.rs +++ b/src/storage/sdr/record/fru_device_locator.rs @@ -68,8 +68,7 @@ impl FruDeviceLocator { }) }; - // NOTE(unwrap): `LogicalUnit::try_from` always succeeds for data masked with 0b11. - let lun = LogicalUnit::try_from((record_data[2] >> 3) & 0b11).unwrap(); + let lun = LogicalUnit::from_low_bits(record_data[2] >> 3); let private_bus_id = record_data[2] & 0b111; let channel_number = record_data[3]; diff --git a/src/storage/sdr/record/mod.rs b/src/storage/sdr/record/mod.rs index 178ffc8..cf2c224 100644 --- a/src/storage/sdr/record/mod.rs +++ b/src/storage/sdr/record/mod.rs @@ -66,9 +66,8 @@ impl SensorKey { // NOTE(unwrap): value is guaranteed to be in the correct range due to mask + shift. let owner_channel = Channel::new((owner_channel_fru_lun & 0xF0) >> 4).unwrap(); - let fru_inv_device_owner_lun = - LogicalUnit::try_from((owner_channel_fru_lun >> 2) & 0x3).unwrap(); - let owner_lun = LogicalUnit::try_from(owner_channel_fru_lun & 0x3).unwrap(); + let fru_inv_device_owner_lun = LogicalUnit::from_low_bits(owner_channel_fru_lun >> 2); + let owner_lun = LogicalUnit::from_low_bits(owner_channel_fru_lun & 0b11); let sensor_number = SensorNumber(NonMaxU8::new(record_data[2]).ok_or(ParseError::InvalidSensorNumber)?); diff --git a/src/storage/sel/mod.rs b/src/storage/sel/mod.rs index b39953b..2167f2b 100644 --- a/src/storage/sel/mod.rs +++ b/src/storage/sel/mod.rs @@ -93,7 +93,7 @@ impl From<(u8, u8)> for EventGenerator { channel_number, } } else { - let lun = (value.1 & 0x3).try_into().unwrap(); + let lun = LogicalUnit::from_low_bits(value.1); Self::RqSAAndLun { i2c_addr: i2c_or_sid,