noodles_cram/io/reader/
container.rs

1mod block;
2pub mod compression_header;
3pub mod header;
4pub mod slice;
5
6use std::{
7    io::{self, Read},
8    iter,
9};
10
11use self::{block::read_block_as, header::read_header};
12pub use self::{compression_header::read_compression_header, slice::read_slice, slice::Slice};
13use crate::container::{CompressionHeader, Header};
14
15/// A CRAM container.
16#[derive(Default)]
17pub struct Container {
18    pub(crate) header: Header,
19    pub(crate) src: Vec<u8>,
20}
21
22impl Container {
23    /// Returns the header.
24    pub fn header(&self) -> &Header {
25        &self.header
26    }
27
28    /// Returns the compression header.
29    pub fn compression_header(&self) -> io::Result<CompressionHeader> {
30        let end = self
31            .header
32            .landmarks
33            .first()
34            .copied()
35            .unwrap_or(self.src.len());
36
37        let mut src = &self.src[..end];
38
39        read_compression_header(&mut src)
40    }
41
42    /// Returns the iterator over slices.
43    pub fn slices(&self) -> impl Iterator<Item = io::Result<Slice<'_>>> + '_ {
44        let landmarks = &self.header.landmarks;
45        let mut i = 0;
46
47        iter::from_fn(move || {
48            if i < landmarks.len() - 1 {
49                let (start, end) = (landmarks[i], landmarks[i + 1]);
50                i += 1;
51                let mut src = &self.src[start..end];
52                Some(read_slice(&mut src))
53            } else if i < landmarks.len() {
54                let start = landmarks[i];
55                i += 1;
56                let mut src = &self.src[start..];
57                Some(read_slice(&mut src))
58            } else {
59                None
60            }
61        })
62    }
63}
64
65pub fn read_container<R>(reader: &mut R, container: &mut Container) -> io::Result<usize>
66where
67    R: Read,
68{
69    match read_header(reader, &mut container.header)? {
70        0 => Ok(0),
71        len => {
72            container.src.resize(len, 0);
73            reader.read_exact(&mut container.src)?;
74            Ok(len)
75        }
76    }
77}