#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CigarOp {
pub op: u8,
pub len: u32,
}
impl CigarOp {
#[must_use]
pub fn from_bam(encoded: u32) -> Self {
Self { op: (encoded & 0xF) as u8, len: encoded >> 4 }
}
#[must_use]
pub fn op_char(&self) -> char {
match self.op {
0 => 'M',
1 => 'I',
2 => 'D',
3 => 'N',
4 => 'S',
5 => 'H',
6 => 'P',
7 => '=',
8 => 'X',
_ => '?',
}
}
}
impl std::fmt::Display for CigarOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.len, self.op_char())
}
}
#[derive(Debug, Clone)]
#[expect(clippy::struct_excessive_bools, reason = "mirrors the C FFI record layout")]
pub struct YaraRecord {
pub read_pair_index: u32,
pub is_read1: bool,
pub contig_id: u32,
pub pos: u32,
pub is_reverse: bool,
pub is_secondary: bool,
pub is_unmapped: bool,
pub mapq: u8,
pub nm: u8,
pub x0: u16,
pub x1: u16,
pub mate_contig_id: u32,
pub mate_pos: u32,
pub tlen: i32,
pub flag: u16,
pub cigar: Vec<CigarOp>,
pub seq: Option<Vec<u8>>,
pub qual: Option<Vec<u8>>,
pub xa: Option<String>,
}
impl YaraRecord {
#[must_use]
pub fn cigar_string(&self) -> String {
use std::fmt::Write;
let mut s = String::with_capacity(self.cigar.len() * 4);
for op in &self.cigar {
write!(s, "{}{}", op.len, op.op_char()).unwrap();
}
s
}
}