pub trait Bcd<T>: Sized {
fn from_bcd(value: T) -> Self;
fn into_bcd(self) -> T;
}
impl Bcd<u8> for u8 {
#[inline]
fn from_bcd(value: u8) -> Self {
value - (value >> 4) * 6
}
#[inline]
fn into_bcd(self) -> u8 {
self + (self / 10) * 6
}
}
impl Bcd<[u8; 2]> for u16 {
#[inline]
fn from_bcd(value: [u8; 2]) -> Self {
u16::from(u8::from_bcd(value[0])) * 100 + u16::from(u8::from_bcd(value[1]))
}
#[inline]
fn into_bcd(self) -> [u8; 2] {
[
((self / 100) as u8).into_bcd(),
((self % 100) as u8).into_bcd(),
]
}
}
impl Bcd<[u8; 4]> for u32 {
#[inline]
fn from_bcd(value: [u8; 4]) -> Self {
(u32::from(u16::from_bcd([value[0], value[1]])) * 10000)
+ u32::from(u16::from_bcd([value[2], value[3]]))
}
#[inline]
fn into_bcd(self) -> [u8; 4] {
let h = ((self / 10000) as u16).into_bcd();
let l = ((self % 10000) as u16).into_bcd();
[h[0], h[1], l[0], l[1]]
}
}
pub trait BcdTime<T>: Sized {
fn from_bcd_time(value: T) -> Self;
fn into_bcd_time(self) -> T;
}
impl BcdTime<[u8; 2]> for u16 {
#[inline]
fn from_bcd_time(value: [u8; 2]) -> Self {
u16::from(u8::from_bcd(value[0]) * 60) + u16::from(u8::from_bcd(value[1]))
}
#[inline]
fn into_bcd_time(self) -> [u8; 2] {
[
((self / 60 % 24) as u8).into_bcd(),
((self % 60) as u8).into_bcd(),
]
}
}
impl BcdTime<[u8; 3]> for u32 {
#[inline]
fn from_bcd_time(value: [u8; 3]) -> Self {
u32::from(u8::from_bcd(value[0])) * 3600
+ u32::from(u8::from_bcd(value[1])) * 60
+ u32::from(u8::from_bcd(value[2]))
}
#[inline]
fn into_bcd_time(self) -> [u8; 3] {
let hm = ((self / 60 % 1440) as u16).into_bcd_time();
let s = ((self % 60) as u8).into_bcd();
[hm[0], hm[1], s]
}
}
impl BcdTime<[u8; 3]> for u64 {
#[inline]
fn from_bcd_time(value: [u8; 3]) -> Self {
u64::from(u8::from_bcd(value[0])) * 3600
+ u64::from(u8::from_bcd(value[1])) * 60
+ u64::from(u8::from_bcd(value[2]))
}
#[inline]
fn into_bcd_time(self) -> [u8; 3] {
let hm = ((self / 60 % 1440) as u16).into_bcd_time();
let s = ((self % 60) as u8).into_bcd();
[hm[0], hm[1], s]
}
}