use crate::error::Error;
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
pub struct LengthFormatIdentifier(pub(crate) u8);
impl LengthFormatIdentifier {
#[inline]
pub fn new(value: u8) -> Result<Self, Error> {
if value > 0x0F {
return Err(Error::InvalidParam(
"`LengthFormatIdentifier` must be between 0x00 and 0xF0".to_string(),
));
}
Ok(Self(value << 4))
}
#[inline]
pub const fn max_number_of_block_length(&self) -> usize {
(self.0 >> 4) as usize
}
}
impl From<LengthFormatIdentifier> for u8 {
fn from(val: LengthFormatIdentifier) -> Self {
val.0
}
}
impl TryFrom<u8> for LengthFormatIdentifier {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
if value > 0xF0 {
return Err(Error::InvalidParam(
"`LengthFormatIdentifier` must be between 0x00 and 0xF0".to_string(),
));
}
Ok(Self(value))
}
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
pub struct DataFormatIdentifier(pub(crate) u8);
impl DataFormatIdentifier {
#[inline]
pub fn new(compression: u8, encryption: u8) -> Self {
Self((compression << 4) | encryption)
}
#[inline]
pub fn compression(&self) -> u8 {
self.0 >> 4
}
#[inline]
pub fn encryption(&self) -> u8 {
self.0 & 0x0F
}
}
impl From<u8> for DataFormatIdentifier {
#[inline]
fn from(v: u8) -> Self {
Self(v)
}
}
impl From<DataFormatIdentifier> for u8 {
#[inline]
fn from(val: DataFormatIdentifier) -> Self {
val.0
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct AddressAndLengthFormatIdentifier(u8);
impl AddressAndLengthFormatIdentifier {
pub fn new(addr_len: u8, size_len: u8) -> Result<Self, Error> {
let value = (size_len << 4) | addr_len;
Self::try_from(value)
}
#[inline]
pub const fn length_of_memory_address(&self) -> usize {
(self.0 & 0x0F) as usize
}
#[inline]
pub const fn length_of_memory_size(&self) -> usize {
((self.0 & 0xF0) >> 4) as usize
}
}
impl From<AddressAndLengthFormatIdentifier> for u8 {
fn from(val: AddressAndLengthFormatIdentifier) -> Self {
val.0
}
}
impl TryFrom<u8> for AddressAndLengthFormatIdentifier {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
if value & 0x0F == 0 || value & 0xF0 == 0 {
return Err(Error::InvalidParam(
"all field of `AddressAndLengthFormatIdentifier` must be rather than 0".into(),
));
}
Ok(Self(value))
}
}