pub type Result<T> = core::result::Result<T, Error>;
#[inline]
#[must_use = "Returned value is not used"]
pub(crate) const fn parity(v: u16) -> u8 {
match v.count_ones() % 2 {
0 => 1,
_ => 0,
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[repr(u8)]
pub enum Error {
OutOfBounds,
InvalidPacket,
InvalidWord,
InvalidString,
MessageFull,
DataFirst,
HeaderNotFirst,
InvalidMessage,
SystemError(SystemError),
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[repr(u8)]
pub enum SystemError {
None,
Terminal(TerminalError),
Subsystem(SubsystemError),
Message(MessageError),
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[repr(u8)]
pub enum TerminalError {
None = 0,
Error = 1,
}
impl TerminalError {
#[must_use = "Returned value is not used"]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
#[must_use = "Returned value is not used"]
pub const fn is_error(&self) -> bool {
matches!(self, Self::Error)
}
}
impl From<u8> for TerminalError {
fn from(value: u8) -> Self {
match value {
1 => Self::Error,
_ => Self::None,
}
}
}
impl From<TerminalError> for u8 {
fn from(value: TerminalError) -> Self {
match value {
TerminalError::Error => 1,
TerminalError::None => 0,
}
}
}
impl From<u16> for TerminalError {
fn from(value: u16) -> Self {
Self::from(value as u8)
}
}
impl From<TerminalError> for u16 {
fn from(value: TerminalError) -> Self {
u8::from(value) as u16
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[repr(u8)]
pub enum SubsystemError {
None = 0,
Error = 1,
}
impl SubsystemError {
#[must_use = "Returned value is not used"]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
#[must_use = "Returned value is not used"]
pub const fn is_error(&self) -> bool {
matches!(self, Self::Error)
}
}
impl From<u8> for SubsystemError {
fn from(value: u8) -> Self {
match value {
1 => Self::Error,
_ => Self::None,
}
}
}
impl From<SubsystemError> for u8 {
fn from(value: SubsystemError) -> Self {
match value {
SubsystemError::Error => 1,
SubsystemError::None => 0,
}
}
}
impl From<u16> for SubsystemError {
fn from(value: u16) -> Self {
Self::from(value as u8)
}
}
impl From<SubsystemError> for u16 {
fn from(value: SubsystemError) -> Self {
u8::from(value) as u16
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[repr(u8)]
pub enum MessageError {
None = 0,
Error = 1,
}
impl MessageError {
#[must_use = "Returned value is not used"]
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
#[must_use = "Returned value is not used"]
pub const fn is_error(&self) -> bool {
matches!(self, Self::Error)
}
}
impl From<u8> for MessageError {
fn from(value: u8) -> Self {
match value {
1 => Self::Error,
_ => Self::None,
}
}
}
impl From<MessageError> for u8 {
fn from(value: MessageError) -> Self {
match value {
MessageError::Error => 1,
MessageError::None => 0,
}
}
}
impl From<u16> for MessageError {
fn from(value: u16) -> Self {
Self::from(value as u8)
}
}
impl From<MessageError> for u16 {
fn from(value: MessageError) -> Self {
u8::from(value) as u16
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parity_0() {
let value = parity(0b1010101010101010);
assert_eq!(value, 1);
}
#[test]
fn test_parity_1() {
let value = parity(0b1010101010101000);
assert_eq!(value, 0);
}
#[test]
fn test_parity_2() {
let value = parity(0b1010101010100000);
assert_eq!(value, 1);
}
#[test]
fn test_parity_3() {
let value = parity(0b1010101010000000);
assert_eq!(value, 0);
}
#[test]
fn test_system_error_clone() {
let error1 = SystemError::Terminal(TerminalError::Error);
let error2 = error1.clone();
assert_eq!(error1, error2);
}
#[test]
fn test_terminal_error_clone() {
let error1 = TerminalError::Error;
let error2 = error1.clone();
assert_eq!(error1, error2);
}
#[test]
fn test_terminal_error() {
let error = TerminalError::None;
assert!(error.is_none());
let error = TerminalError::Error;
assert!(error.is_error());
}
#[test]
fn test_terminal_error_from_u8() {
let error = TerminalError::from(0u8);
assert!(error.is_none());
let error = TerminalError::from(1u8);
assert!(error.is_error());
}
#[test]
fn test_u8_from_terminal_error() {
let error = u8::from(TerminalError::None);
assert_eq!(error, 0);
let error = u8::from(TerminalError::Error);
assert_eq!(error, 1);
}
#[test]
fn test_terminal_error_from_u16() {
let error = TerminalError::from(0u16);
assert!(error.is_none());
let error = TerminalError::from(1u16);
assert!(error.is_error());
}
#[test]
fn test_u16_from_terminal_error() {
let error = u16::from(TerminalError::None);
assert_eq!(error, 0);
let error = u16::from(TerminalError::Error);
assert_eq!(error, 1);
}
#[test]
fn test_subsystem_error_clone() {
let error1 = SubsystemError::Error;
let error2 = error1.clone();
assert_eq!(error1, error2);
}
#[test]
fn test_subsystem_error() {
let error = SubsystemError::None;
assert!(error.is_none());
let error = SubsystemError::Error;
assert!(error.is_error());
}
#[test]
fn test_subsystem_error_from_u8() {
let error = SubsystemError::from(0u8);
assert!(error.is_none());
let error = SubsystemError::from(1u8);
assert!(error.is_error());
}
#[test]
fn test_u8_from_subsystem_error() {
let error = u8::from(SubsystemError::None);
assert_eq!(error, 0);
let error = u8::from(SubsystemError::Error);
assert_eq!(error, 1);
}
#[test]
fn test_subsystem_error_from_u16() {
let error = SubsystemError::from(0u16);
assert!(error.is_none());
let error = SubsystemError::from(1u16);
assert!(error.is_error());
}
#[test]
fn test_u16_from_subsystem_error() {
let error = u16::from(SubsystemError::None);
assert_eq!(error, 0);
let error = u16::from(SubsystemError::Error);
assert_eq!(error, 1);
}
#[test]
fn test_message_error_clone() {
let error1 = MessageError::Error;
let error2 = error1.clone();
assert_eq!(error1, error2);
}
#[test]
fn test_message_error() {
let error = MessageError::None;
assert!(error.is_none());
let error = MessageError::Error;
assert!(error.is_error());
}
#[test]
fn test_message_error_from_u8() {
let error = MessageError::from(0u8);
assert!(error.is_none());
let error = MessageError::from(1u8);
assert!(error.is_error());
}
#[test]
fn test_u8_from_message_error() {
let error = u8::from(MessageError::None);
assert_eq!(error, 0);
let error = u8::from(MessageError::Error);
assert_eq!(error, 1);
}
#[test]
fn test_message_error_from_u16() {
let error = MessageError::from(0u16);
assert!(error.is_none());
let error = MessageError::from(1u16);
assert!(error.is_error());
}
#[test]
fn test_u16_from_message_error() {
let error = u16::from(MessageError::None);
assert_eq!(error, 0);
let error = u16::from(MessageError::Error);
assert_eq!(error, 1);
}
}