d4_hts/alignment/
alignment_impl.rs

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