use std::convert::{TryFrom, TryInto};
use std::fmt;
use std::u32;
use crate::error::Error;
#[derive(Debug, Copy, Clone)]
pub enum Nucleotide {
T,
C,
A,
G,
N,
}
impl Nucleotide {
#[must_use]
pub const fn bits(&self) -> u8 {
match self {
Self::T | Self::N => 0,
Self::C => 1,
Self::A => 2,
Self::G => 3,
}
}
}
impl TryFrom<u8> for Nucleotide {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
84 | 85 | 116 | 117 => Ok(Self::T), 67 | 99 => Ok(Self::C),
65 | 97 => Ok(Self::A),
71 | 103 => Ok(Self::G),
78 => Ok(Self::N),
_ => Err(Error::FileFormat(format!(
"Bad ascii value for nucleotide: {}",
value
))),
}
}
}
impl TryFrom<char> for Nucleotide {
type Error = Error;
fn try_from(value: char) -> Result<Self, Self::Error> {
let numeric: u32 = value.into();
let numeric: u8 = numeric
.try_into()
.map_err(|_| Self::Error::BadNucleotide(value))?;
numeric.try_into()
}
}
impl fmt::Display for Nucleotide {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c = match self {
Self::T => 'T',
Self::C => 'C',
Self::A => 'A',
Self::G => 'G',
Self::N => 'N',
};
write!(f, "{}", c)
}
}