use std::io;
use crate::alignment::record::cigar::Op;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Cigar(Vec<Op>);
impl Cigar {
pub fn alignment_span(&self) -> usize {
self.0
.iter()
.filter_map(|op| op.kind().consumes_reference().then_some(op.len()))
.sum()
}
pub fn read_length(&self) -> usize {
self.0
.iter()
.filter_map(|op| op.kind().consumes_read().then_some(op.len()))
.sum()
}
}
impl crate::alignment::record::Cigar for Cigar {
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn len(&self) -> usize {
self.0.len()
}
fn iter(&self) -> Box<dyn Iterator<Item = io::Result<Op>> + '_> {
Box::new(self.0.iter().copied().map(Ok))
}
}
impl crate::alignment::record::Cigar for &Cigar {
fn is_empty(&self) -> bool {
(*self).is_empty()
}
fn len(&self) -> usize {
(*self).len()
}
fn iter(&self) -> Box<dyn Iterator<Item = io::Result<Op>> + '_> {
(*self).iter()
}
}
impl AsRef<[Op]> for Cigar {
fn as_ref(&self) -> &[Op] {
&self.0
}
}
impl AsMut<Vec<Op>> for Cigar {
fn as_mut(&mut self) -> &mut Vec<Op> {
&mut self.0
}
}
impl Extend<Op> for Cigar {
fn extend<T: IntoIterator<Item = Op>>(&mut self, iter: T) {
self.0.extend(iter);
}
}
impl FromIterator<Op> for Cigar {
fn from_iter<T: IntoIterator<Item = Op>>(iter: T) -> Self {
let mut cigar = Cigar::default();
cigar.extend(iter);
cigar
}
}
impl From<Vec<Op>> for Cigar {
fn from(ops: Vec<Op>) -> Self {
Self(ops)
}
}
impl From<Cigar> for Vec<Op> {
fn from(cigar: Cigar) -> Self {
cigar.0
}
}