#![allow(clippy::unreadable_literal)]
#![allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Model<T> {
pub width: u32,
pub poly: T,
pub init: T,
pub refin: bool,
pub refout: bool,
pub xorout: T,
pub check: T,
pub residue: T,
pub name: Option<&'static str>,
}
#[cfg(not(feature = "std"))]
use core::convert::TryFrom;
#[cfg(feature = "std")]
use std::convert::TryFrom;
macro_rules! impl_alg_from {
(u128) => {}; ($T:ident) => {
#[cfg(feature = "crc-catalog")]
impl From<crc_catalog::Algorithm<$T>> for Model<$T> {
fn from(value: crc_catalog::Algorithm<$T>) -> Self {
Model {
width: value.width.into(),
poly: value.poly,
init: value.init,
refin: value.refin,
refout: value.refout,
xorout: value.xorout,
check: value.check,
residue: value.residue,
name: None,
}
}
}
#[cfg(feature = "crc-catalog")]
impl From<Model<$T>> for crc_catalog::Algorithm<$T> {
fn from(value: Model<$T>) -> Self {
Self {
width: u8::try_from(value.width).expect("model bit width does not fit in u8"),
poly: value.poly,
init: value.init,
refin: value.refin,
refout: value.refout,
xorout: value.xorout,
check: value.check,
residue: value.residue,
}
}
}
#[cfg(test)]
impl From<crc::Algorithm<$T>> for Model<$T> {
fn from(value: crc::Algorithm<$T>) -> Self {
Model {
width: <$T>::BITS,
poly: value.poly,
init: value.init,
refin: value.refin,
refout: value.refout,
xorout: value.xorout,
check: value.check,
residue: value.residue,
name: None,
}
}
}
#[cfg(test)]
impl TryFrom<Model<$T>> for crc::Algorithm<$T> {
type Error = &'static str;
fn try_from(value: Model<$T>) -> Result<Self, Self::Error> {
if <$T>::BITS != value.width {
return Err("width is not exactly word size");
}
Ok(Self {
poly: value.poly,
init: value.init,
refin: value.refin,
refout: value.refout,
xorout: value.xorout,
check: value.check,
residue: value.residue,
})
}
}
};
($T:ident => $U:ident) => {
impl TryFrom<Model<$T>> for Model<$U> {
type Error = &'static str;
fn try_from(value: Model<$T>) -> Result<Self, Self::Error> {
if value.width > <$U>::BITS {
return Err("width does not fit");
}
Ok(Model {
width: value.width,
poly: <$U>::try_from(value.poly).map_err(|_| "poly does not fit")?,
init: <$U>::try_from(value.init).map_err(|_| "init does not fit")?,
refin: value.refin,
refout: value.refout,
xorout: <$U>::try_from(value.xorout).map_err(|_| "xorout does not fit")?,
check: <$U>::try_from(value.check).map_err(|_| "check does not fit")?,
residue: <$U>::try_from(value.residue).map_err(|_| "residue does not fit")?,
name: value.name,
})
}
}
};
($A:ident, $($rest:ident),+) => {
$(
impl_alg_from!($A => $rest);
impl_alg_from!($rest => $A);
)*
impl_alg_from!($A);
impl_alg_from!($($rest),*);
};
}
impl_alg_from!(u8, u16, u32, u64, u128);
#[path = "generated_models.rs"]
mod generated_models;
pub use generated_models::*;