use std::borrow::Cow;
use std::ops::BitOr;
use std::ops::BitOrAssign;
#[derive(Debug, Clone, PartialEq)]
pub enum MaskUnit {
Masked(u64),
Unmasked(u64),
}
#[derive(Debug, Clone, Default)]
pub struct Record<'a> {
pub id: Option<Cow<'a, str>>,
pub comment: Option<Cow<'a, str>>,
pub sequence: Option<Cow<'a, str>>,
pub quality: Option<Cow<'a, str>>,
pub length: Option<u64>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub enum FormatVersion {
#[default]
V1 = 1,
V2 = 2,
}
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub enum SequenceType {
#[default]
Dna = 0,
Rna = 1,
Protein = 2,
Text = 3,
}
impl SequenceType {
#[inline]
pub const fn is_nucleotide(&self) -> bool {
match self {
Self::Dna | Self::Rna => true,
Self::Protein | Self::Text => false,
}
}
}
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Flag {
Quality = 0x1,
Sequence = 0x2,
Mask = 0x4,
Length = 0x8,
Comment = 0x10,
Id = 0x20,
Title = 0x40,
Extended = 0x80,
}
impl Flag {
pub const fn values() -> &'static [Self] {
&[
Flag::Quality,
Flag::Sequence,
Flag::Mask,
Flag::Length,
Flag::Comment,
Flag::Id,
Flag::Title,
Flag::Extended,
]
}
pub const fn as_byte(&self) -> u8 {
*self as u8
}
}
impl BitOr<Flag> for Flag {
type Output = Flags;
fn bitor(self, rhs: Flag) -> Self::Output {
Flags((self as u8).bitor(rhs as u8))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Flags(u8);
impl Flags {
pub const fn new() -> Self {
Self(0)
}
pub const fn test(&self, flag: Flag) -> bool {
(self.0 & flag as u8) != 0
}
pub fn set(&mut self, flag: Flag) {
self.0 |= flag as u8;
}
pub fn unset(&mut self, flag: Flag) {
self.0 &= !(flag as u8);
}
pub const fn as_byte(&self) -> u8 {
self.0
}
}
impl Default for Flags {
fn default() -> Self {
Self::new()
}
}
impl From<Flag> for Flags {
fn from(value: Flag) -> Self {
Self(value.as_byte())
}
}
impl From<Flags> for u8 {
fn from(flags: Flags) -> Self {
flags.0
}
}
impl BitOr<Flag> for Flags {
type Output = Flags;
fn bitor(self, rhs: Flag) -> Self::Output {
Flags(self.0.bitor(rhs as u8))
}
}
impl BitOrAssign<Flag> for Flags {
fn bitor_assign(&mut self, rhs: Flag) {
self.0 = self.0 | rhs as u8;
}
}
#[derive(Debug, Clone)]
pub struct Header {
pub(crate) format_version: FormatVersion,
pub(crate) sequence_type: SequenceType,
pub(crate) flags: Flags,
pub(crate) name_separator: char,
pub(crate) line_length: u64,
pub(crate) number_of_sequences: u64,
}
impl Header {
pub const fn flags(&self) -> Flags {
self.flags
}
pub const fn line_length(&self) -> u64 {
self.line_length
}
pub const fn name_separator(&self) -> char {
self.name_separator
}
pub const fn number_of_sequences(&self) -> u64 {
self.number_of_sequences
}
pub const fn sequence_type(&self) -> SequenceType {
self.sequence_type
}
pub const fn format_version(&self) -> FormatVersion {
self.format_version
}
}
impl Default for Header {
fn default() -> Self {
Header {
format_version: FormatVersion::V1,
sequence_type: SequenceType::Dna,
flags: Flags::default(),
name_separator: ' ',
line_length: 60,
number_of_sequences: 0,
}
}
}