use core::fmt;
use core::fmt::Display;
#[cfg(feature = "std")]
use std::error;
use crate::phys::{
BigLittleEndianDecoder, BigLittleEndianEncoder, BinaryDecodeError, BinaryDecoder,
BinaryEncodeError, BinaryEncoder, EndianOrder,
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum ChecksumType {
Inherit = 0,
On = 1,
Off = 2,
Label = 3,
GangHeader = 4,
Zilog = 5,
Fletcher2 = 6,
Fletcher4 = 7,
Sha256 = 8,
Zilog2 = 9,
NoParity = 10,
Sha512_256 = 11,
Skein = 12,
Edonr = 13,
Blake3 = 14,
}
impl Display for ChecksumType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumType::Inherit => write!(f, "Inherit"),
ChecksumType::On => write!(f, "On"),
ChecksumType::Off => write!(f, "Off"),
ChecksumType::Label => write!(f, "Label"),
ChecksumType::GangHeader => write!(f, "GangHeader"),
ChecksumType::Zilog => write!(f, "Zilog"),
ChecksumType::Fletcher2 => write!(f, "Fletcher2"),
ChecksumType::Fletcher4 => write!(f, "Fletcher4"),
ChecksumType::Sha256 => write!(f, "Sha256"),
ChecksumType::Zilog2 => write!(f, "Zilog2"),
ChecksumType::NoParity => write!(f, "NoParity"),
ChecksumType::Sha512_256 => write!(f, "Sha512_256"),
ChecksumType::Skein => write!(f, "Skein"),
ChecksumType::Edonr => write!(f, "Edonr"),
ChecksumType::Blake3 => write!(f, "Blake3"),
}
}
}
impl From<ChecksumType> for u8 {
fn from(val: ChecksumType) -> u8 {
val as u8
}
}
impl TryFrom<u8> for ChecksumType {
type Error = ChecksumTypeError;
fn try_from(checksum: u8) -> Result<Self, Self::Error> {
match checksum {
0 => Ok(ChecksumType::Inherit),
1 => Ok(ChecksumType::On),
2 => Ok(ChecksumType::Off),
3 => Ok(ChecksumType::Label),
4 => Ok(ChecksumType::GangHeader),
5 => Ok(ChecksumType::Zilog),
6 => Ok(ChecksumType::Fletcher2),
7 => Ok(ChecksumType::Fletcher4),
8 => Ok(ChecksumType::Sha256),
9 => Ok(ChecksumType::Zilog2),
10 => Ok(ChecksumType::NoParity),
11 => Ok(ChecksumType::Sha512_256),
12 => Ok(ChecksumType::Skein),
13 => Ok(ChecksumType::Edonr),
14 => Ok(ChecksumType::Blake3),
_ => Err(ChecksumTypeError::Unknown { checksum }),
}
}
}
#[derive(Debug)]
pub enum ChecksumTypeError {
Unknown {
checksum: u8,
},
}
impl fmt::Display for ChecksumTypeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumTypeError::Unknown { checksum } => {
write!(f, "Unknown ChecksumType {checksum}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for ChecksumTypeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
None
}
}
#[derive(Debug)]
pub struct ChecksumValue {
pub words: [u64; 4],
}
impl ChecksumValue {
pub const SIZE: usize = 32;
pub fn from_decoder(
decoder: &mut dyn BinaryDecoder<'_>,
) -> Result<ChecksumValue, ChecksumValueDecodeError> {
Ok(ChecksumValue {
words: [
decoder.get_u64()?,
decoder.get_u64()?,
decoder.get_u64()?,
decoder.get_u64()?,
],
})
}
pub fn to_encoder(
&self,
encoder: &mut dyn BinaryEncoder<'_>,
) -> Result<(), ChecksumValueEncodeError> {
encoder.put_u64(self.words[0])?;
encoder.put_u64(self.words[1])?;
encoder.put_u64(self.words[2])?;
encoder.put_u64(self.words[3])?;
Ok(())
}
}
#[derive(Debug)]
pub enum ChecksumValueDecodeError {
Binary {
err: BinaryDecodeError,
},
}
impl From<BinaryDecodeError> for ChecksumValueDecodeError {
fn from(err: BinaryDecodeError) -> Self {
ChecksumValueDecodeError::Binary { err }
}
}
impl fmt::Display for ChecksumValueDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumValueDecodeError::Binary { err } => {
write!(f, "ChecksumValue decode error | {err}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for ChecksumValueDecodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ChecksumValueDecodeError::Binary { err } => Some(err),
}
}
}
#[derive(Debug)]
pub enum ChecksumValueEncodeError {
Binary {
err: BinaryEncodeError,
},
}
impl From<BinaryEncodeError> for ChecksumValueEncodeError {
fn from(err: BinaryEncodeError) -> Self {
ChecksumValueEncodeError::Binary { err }
}
}
impl fmt::Display for ChecksumValueEncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumValueEncodeError::Binary { err } => {
write!(f, "ChecksumValue encode error | {err}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for ChecksumValueEncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ChecksumValueEncodeError::Binary { err } => Some(err),
}
}
}
#[derive(Debug)]
pub struct ChecksumTail {
pub order: EndianOrder,
pub value: ChecksumValue,
}
impl ChecksumTail {
pub const SIZE: usize = 8 + ChecksumValue::SIZE;
pub const MAGIC: u64 = 0x0210da7ab10c7a11;
pub fn from_bytes(
bytes: &[u8; ChecksumTail::SIZE],
) -> Result<ChecksumTail, ChecksumTailDecodeError> {
let mut bele_decoder = BigLittleEndianDecoder::from_u64_magic(bytes, ChecksumTail::MAGIC)?;
let decoder = bele_decoder.decoder_as_mut();
Ok(ChecksumTail {
order: decoder.order(),
value: ChecksumValue::from_decoder(decoder)?,
})
}
pub fn to_bytes(
&self,
bytes: &mut [u8; ChecksumTail::SIZE],
) -> Result<(), ChecksumTailEncodeError> {
let mut bl_encoder = BigLittleEndianEncoder::to_bytes(bytes, self.order);
let encoder = bl_encoder.encoder();
encoder.put_u64(ChecksumTail::MAGIC)?;
self.value.to_encoder(encoder)?;
Ok(())
}
}
#[derive(Debug)]
pub enum ChecksumTailDecodeError {
Binary {
err: BinaryDecodeError,
},
ChecksumValue {
err: ChecksumValueDecodeError,
},
}
impl From<BinaryDecodeError> for ChecksumTailDecodeError {
fn from(value: BinaryDecodeError) -> Self {
ChecksumTailDecodeError::Binary { err: value }
}
}
impl From<ChecksumValueDecodeError> for ChecksumTailDecodeError {
fn from(value: ChecksumValueDecodeError) -> Self {
ChecksumTailDecodeError::ChecksumValue { err: value }
}
}
impl fmt::Display for ChecksumTailDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumTailDecodeError::Binary { err } => {
write!(f, "ChecksumTail decode error | {err}")
}
ChecksumTailDecodeError::ChecksumValue { err } => {
write!(f, "ChecksumTail decode error | {err}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for ChecksumTailDecodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ChecksumTailDecodeError::Binary { err } => Some(err),
ChecksumTailDecodeError::ChecksumValue { err } => Some(err),
}
}
}
#[derive(Debug)]
pub enum ChecksumTailEncodeError {
Binary {
err: BinaryEncodeError,
},
ChecksumValue {
err: ChecksumValueEncodeError,
},
}
impl From<BinaryEncodeError> for ChecksumTailEncodeError {
fn from(err: BinaryEncodeError) -> Self {
ChecksumTailEncodeError::Binary { err }
}
}
impl From<ChecksumValueEncodeError> for ChecksumTailEncodeError {
fn from(err: ChecksumValueEncodeError) -> Self {
ChecksumTailEncodeError::ChecksumValue { err }
}
}
impl fmt::Display for ChecksumTailEncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ChecksumTailEncodeError::Binary { err } => {
write!(f, "ChecksumTail encode error | {err}")
}
ChecksumTailEncodeError::ChecksumValue { err } => {
write!(f, "ChecksumTail encode error | {err}")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for ChecksumTailEncodeError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ChecksumTailEncodeError::Binary { err } => Some(err),
ChecksumTailEncodeError::ChecksumValue { err } => Some(err),
}
}
}