1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use super::error::AlignmentError; use super::htslib::*; use super::BamFile; use std::ptr::null_mut; pub struct Alignment<'a> { data_obj: *mut bam1_t, file: &'a BamFile, } impl<'a> std::fmt::Debug for Alignment<'a> { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { write!(fmt, "<Alignment>") } } impl<'a> Alignment<'a> { pub(super) fn new(data_obj: *mut bam1_t, file: &'a BamFile) -> Self { Self { data_obj, file } } pub(super) fn hts_obj(&self) -> &bam1_t { unsafe { &*self.data_obj } } } impl<'a> Drop for Alignment<'a> { fn drop(&mut self) { self.file.free_inner_obj(self.data_obj); } } pub trait AlignmentReader<'a> { fn start(&self) -> (u32, u32); fn get_file(&self) -> &'a BamFile; fn next(&self, buf: *mut bam1_t) -> Result<Option<Alignment<'a>>, AlignmentError>; fn to_alignment_iter(self) -> AlignmentIter<'a, Self> where Self: Sized, { AlignmentIter { reader: self, p: std::marker::PhantomData, } } } pub struct AlignmentIter<'a, R: AlignmentReader<'a>> { reader: R, p: std::marker::PhantomData<&'a i32>, } impl<'a, R: AlignmentReader<'a>> Iterator for AlignmentIter<'a, R> { type Item = Result<Alignment<'a>, AlignmentError>; fn next(&mut self) -> Option<Self::Item> { if let Ok(buf) = self.reader.get_file().alloc_inner_obj() { if buf == null_mut() { return Some(Err((-1).into())); } let rc = self.reader.next(buf); if let Ok(Some(ref _t)) = rc { } else { self.reader.get_file().free_inner_obj(buf); } return match rc { Ok(Some(otherwise)) => Some(Ok(otherwise)), Ok(None) => None, Err(AlignmentError::HtsError(-1)) => None, Err(whatever) => Some(Err(whatever)), }; } return Some(Err((-1).into())); } }