d4_hts/alignment/
alignment_impl.rs1use 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}