pub struct DnaDisambiguation;
impl DnaDisambiguation {
const TABLE: &[u8; 256] = &IUPAC_DISAMBIGUATION;
#[must_use]
pub fn maybe_std_stop_codon(codon: [u8; 3]) -> bool {
Self::maybe_t(codon[0]) && {
let encoded1 = Self::TABLE[codon[1] as usize];
let encoded2 = Self::TABLE[codon[2] as usize];
(encoded1 & (MAYBE_A | MAYBE_G) > 0)
&& (encoded2 & (MAYBE_A | MAYBE_G) > 0)
&& ((encoded1 | encoded2) & MAYBE_A > 0)
}
}
#[must_use]
pub fn maybe_a(base: u8) -> bool {
Self::TABLE[base as usize] & MAYBE_A > 0
}
#[must_use]
pub fn maybe_c(base: u8) -> bool {
Self::TABLE[base as usize] & MAYBE_C > 0
}
#[must_use]
pub fn maybe_g(base: u8) -> bool {
Self::TABLE[base as usize] & MAYBE_G > 0
}
#[must_use]
pub fn maybe_t(base: u8) -> bool {
Self::TABLE[base as usize] & MAYBE_T > 0
}
#[must_use]
pub fn maybe_ac(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_C) > 0
}
#[must_use]
pub fn maybe_ag(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_G) > 0
}
#[must_use]
pub fn maybe_at(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_cg(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_C | MAYBE_G) > 0
}
#[must_use]
pub fn maybe_ct(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_C | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_gt(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_G | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_acg(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_C | MAYBE_G) > 0
}
#[must_use]
pub fn maybe_act(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_C | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_agt(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_A | MAYBE_G | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_cgt(base: u8) -> bool {
Self::TABLE[base as usize] & (MAYBE_C | MAYBE_G | MAYBE_T) > 0
}
#[must_use]
pub fn maybe_acgt(base: u8) -> bool {
Self::TABLE[base as usize] > 0
}
}
const MAYBE_A: u8 = 0b0001;
const MAYBE_C: u8 = 0b0010;
const MAYBE_G: u8 = 0b0100;
const MAYBE_T: u8 = 0b1000;
const IUPAC_DISAMBIGUATION: [u8; 256] = {
const fn fill(byte: u8, to: &[u8], out: &mut [u8; 256]) {
let lower = byte.to_ascii_lowercase();
let upper = byte.to_ascii_uppercase();
let mut to_encoded = 0;
let mut i = 0;
while i < to.len() {
let bit = match to[i] {
b'A' => MAYBE_A,
b'C' => MAYBE_C,
b'G' => MAYBE_G,
b'T' => MAYBE_T,
_ => panic!("Invalid byte found"),
};
to_encoded |= bit;
i += 1;
}
out[lower as usize] = to_encoded;
out[upper as usize] = to_encoded;
}
let mut out = [0; 256];
fill(b'A', b"A", &mut out);
fill(b'C', b"C", &mut out);
fill(b'G', b"G", &mut out);
fill(b'T', b"T", &mut out);
fill(b'U', b"T", &mut out);
fill(b'R', b"AG", &mut out);
fill(b'Y', b"CT", &mut out);
fill(b'S', b"GC", &mut out);
fill(b'W', b"AT", &mut out);
fill(b'K', b"GT", &mut out);
fill(b'M', b"AC", &mut out);
fill(b'B', b"CGT", &mut out);
fill(b'D', b"AGT", &mut out);
fill(b'H', b"ACT", &mut out);
fill(b'V', b"ACG", &mut out);
fill(b'N', b"ACGT", &mut out);
out
};