use super::{Display, Frame, ParseError};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Debug, Display, Copy, Clone)]
#[repr(align(8))]
pub struct Odometer(u32);
impl Odometer {
pub fn kilometers(self) -> f64 {
f64::from(self.0) / 100.0
}
pub fn miles(self) -> f64 {
self.kilometers() * 0.621371
}
pub const fn raw(self) -> u32 {
self.0
}
}
impl TryFrom<Frame> for Odometer {
type Error = ParseError;
fn try_from(frame: Frame) -> Result<Self, Self::Error> {
const ID: u32 = 0x3d2;
const LEN: usize = 4;
if frame.id() != ID {
return Err(ParseError::Id { frame });
}
let data: [u8; LEN] = match frame.data().try_into() {
Ok(data) => data,
Err(_) => {
return Err(ParseError::Len {
frame,
expected: LEN,
})
}
};
Ok(Odometer(u32::from_be_bytes(data)))
}
}