#[derive(Debug, Clone)]
pub struct SeqRecord {
pub name: Vec<u8>,
pub comment: Option<Vec<u8>>,
pub seq: Vec<u8>,
pub qual: Option<Vec<u8>>,
}
impl SeqRecord {
#[inline]
pub fn new(name: Vec<u8>, seq: Vec<u8>) -> Self {
Self {
name,
comment: None,
seq,
qual: None,
}
}
#[inline]
pub fn with_qual(name: Vec<u8>, seq: Vec<u8>, qual: Vec<u8>) -> Self {
Self {
name,
comment: None,
seq,
qual: Some(qual),
}
}
#[inline]
pub fn is_fastq(&self) -> bool {
self.qual.is_some()
}
#[inline]
pub fn len(&self) -> usize {
self.seq.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.seq.is_empty()
}
pub fn reverse_complement(&mut self, comp_table: &[u8; 256]) {
self.seq.reverse();
for base in &mut self.seq {
*base = comp_table[*base as usize];
}
if let Some(qual) = &mut self.qual {
qual.reverse();
}
}
pub fn clear(&mut self) {
self.name.clear();
self.comment = None;
self.seq.clear();
self.qual = None;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_seq_record_basic() {
let record = SeqRecord::new(b"seq1".to_vec(), b"ACGT".to_vec());
assert_eq!(record.name, b"seq1");
assert_eq!(record.seq, b"ACGT");
assert_eq!(record.len(), 4);
assert!(!record.is_fastq());
assert!(!record.is_empty());
}
#[test]
fn test_seq_record_with_qual() {
let record = SeqRecord::with_qual(b"seq1".to_vec(), b"ACGT".to_vec(), b"IIII".to_vec());
assert!(record.is_fastq());
assert_eq!(record.qual, Some(b"IIII".to_vec()));
}
#[test]
fn test_clear() {
let mut record = SeqRecord::with_qual(b"seq1".to_vec(), b"ACGT".to_vec(), b"IIII".to_vec());
record.clear();
assert!(record.name.is_empty());
assert!(record.seq.is_empty());
assert!(record.comment.is_none());
assert!(record.qual.is_none());
}
}