use std::fmt::{self, Display};
use std::str::FromStr;
use crate::common::Result;
use crate::Exceptions;
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub enum ErrorCorrectionLevel {
L,
M,
Q,
H, Invalid,
}
impl ErrorCorrectionLevel {
pub fn forBits(bits: u8) -> Result<Self> {
match bits {
0 => Ok(Self::M),
1 => Ok(Self::L),
2 => Ok(Self::H),
3 => Ok(Self::Q),
_ => Err(Exceptions::illegal_argument_with(format!(
"{bits} is not a valid bit selection"
))),
}
}
pub fn get_value(&self) -> u8 {
match self {
ErrorCorrectionLevel::L => 0x01,
ErrorCorrectionLevel::M => 0x00,
ErrorCorrectionLevel::Q => 0x03,
ErrorCorrectionLevel::H => 0x02,
ErrorCorrectionLevel::Invalid => 0x00,
}
}
pub fn get_ordinal(&self) -> u8 {
match self {
ErrorCorrectionLevel::L => 0,
ErrorCorrectionLevel::M => 1,
ErrorCorrectionLevel::Q => 2,
ErrorCorrectionLevel::H => 3,
ErrorCorrectionLevel::Invalid => 100,
}
}
}
impl TryFrom<u8> for ErrorCorrectionLevel {
type Error = Exceptions;
fn try_from(value: u8) -> Result<Self, Self::Error> {
ErrorCorrectionLevel::forBits(value)
}
}
impl From<ErrorCorrectionLevel> for u8 {
fn from(value: ErrorCorrectionLevel) -> Self {
value.get_value()
}
}
impl FromStr for ErrorCorrectionLevel {
type Err = Exceptions;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let as_str = match s.to_uppercase().as_str() {
"L" => Some(ErrorCorrectionLevel::L),
"M" => Some(ErrorCorrectionLevel::M),
"Q" => Some(ErrorCorrectionLevel::Q),
"H" => Some(ErrorCorrectionLevel::H),
_ => None,
};
if let Some(as_str) = as_str {
return Ok(as_str);
}
let number_possible = s.parse::<u8>();
if let Ok(number_possible) = number_possible {
return number_possible.try_into();
}
Err(Exceptions::illegal_argument_with(format!(
"could not parse {s} into an ec level"
)))
}
}
impl Display for ErrorCorrectionLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
ErrorCorrectionLevel::L => "L",
ErrorCorrectionLevel::M => "M",
ErrorCorrectionLevel::Q => "Q",
ErrorCorrectionLevel::H => "H",
ErrorCorrectionLevel::Invalid => "_",
})
}
}