use std::fmt::format;
use crate::constant::{EFF_MASK, SFF_MASK, SFF_MASK_INV};
use crate::j1939::J1939Id;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Id {
Standard(u16),
Extended(u32),
J1939(J1939Id),
}
impl Id {
#[inline]
pub fn from_bits(bits: u32, extended: bool) -> Self {
let bits = bits & EFF_MASK;
if extended {
Self::Extended(bits)
}
else {
if bits & SFF_MASK_INV > 0 {
Self::Extended(bits)
}
else {
Self::Standard(bits as u16)
}
}
}
#[inline]
pub fn from_hex(hex_str: &str, extended: bool) -> Self {
let bits = u32::from_str_radix(hex_str, 16).unwrap_or_default();
Self::from_bits(bits, extended)
}
#[inline]
pub fn try_from_bits(bits: u32, extended: bool) -> Option<Self> {
if bits > EFF_MASK { None }
else { Some(Self::from_bits(bits, extended)) }
}
#[inline]
pub fn try_from_hex(hex_str: &str, extended: bool) -> Option<Self> {
match u32::from_str_radix(hex_str, 16) {
Ok(bits) => Self::try_from_bits(bits, extended),
Err(_) => None,
}
}
#[inline]
pub fn into_bits(self) -> u32 {
match self {
Self::Standard(v) => v as u32,
Self::Extended(v) => v,
Self::J1939(v) => v.into_bits(),
}
}
#[inline]
pub fn into_hex(self) -> String {
format(format_args!("{:08X}", self.into_bits()))
}
#[inline]
#[must_use]
pub fn as_raw(self) -> u32 {
self.into_bits()
}
#[inline]
#[must_use]
pub fn standard_id(self) -> Self {
match self {
Self::Standard(_) => self.clone(),
Self::Extended(v) => Self::Standard((v >> 18) as u16), Self::J1939(v) => Self::Standard((v.into_bits() >> 18) as u16)
}
}
#[inline]
pub fn is_extended(&self) -> bool {
match self {
Self::Standard(_) => false,
Self::Extended(v) => (*v & !SFF_MASK) > 0,
Self::J1939(_) => true,
}
}
}