// ahda: Pseudoalignment compression and conversion between formats.
//
// Copyright 2025 Tommi Mäklin [tommi@maklin.fi].
//
// Copyrights in this project are retained by contributors. No copyright assignment
// is required to contribute to this project.
//
// Except as otherwise noted (below and/or in individual files), this
// project is licensed under the Apache License, Version 2.0
// <LICENSE-APACHE> or <http://www.apache.org/licenses/LICENSE-2.0> or
// the MIT license, <LICENSE-MIT> or <http://opensource.org/licenses/MIT>,
// at your option.
//
//! Decoder implementations from [Read] and bitmap iterators.
//!
//! Contains implementations for two core classes:
//!
//! - [Decoder]: reads the .ahda binary format from a connection implementing
//! [Read] and returns blocks of [PseudoAln] records when [Decoder::next] is called.
//!
//! - [BitmapDecoder](bitmap_decoder::BitmapDecoder): decodes a [PseudoAln] record from
//! any struct that returns u64 indexes of aligned bits in a flattened
//! pseudoalignment. Currently, the intended use case is with
//! [RoaringBitmap] or
//! [RoaringTreemap] but in principle works with
//! other structs that implement a similar iterator.
//!
//! Internally, Decoder reads in a single block at a time and uses BitmapDecoder
//! to retrieve the alignments.
//!
//! BitmapDecoder will only return alignments that have some hits.
//!
//! Decoder will pad the output from BitmapDecoder to include queries that are
//! included in [BlockFlags] but did not align against any target.
//!
//! ## Usage
//!
//! ### Decoder
//!
//! Decoder is useful for reading all alignments or a block of alignments from a stream.
//!
//! ```rust
//! use ahda::{encode_from_read_to_write, decode_from_read_to_write};
//! use ahda::EncodeOpts;
//! use ahda::{Format, PseudoAln};
//! use ahda::decoder::Decoder;
//! use std::io::{Cursor, Seek};
//!
//! // First set up some mock encoded data
//! let targets = vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec(), "virus.fasta".as_bytes().to_vec()];
//! let queries = vec![b"r1".to_vec(), b"r2".to_vec(), b"r651903".to_vec(), b"r7543".to_vec(), b"r16".to_vec()];
//! let name = "sample".as_bytes().to_vec();
//!
//! // Have this input data:
//! // 3 r7543 chr.fasta:virus.fasta
//! // 0 r1 virus.fasta
//! // 4 r16 chr.fasta:plasmid.fasta:virus.fasta
//! // 2 r651903
//! //
//! let mut input_bytes: Vec<u8> = Vec::new();
//! input_bytes.append(&mut b"0\tr1\tvirus.fasta\n".to_vec());
//! input_bytes.append(&mut b"3\tr7543\tchr.fasta:virus.fasta\n".to_vec());
//! input_bytes.append(&mut b"4\tr16\tchr.fasta:plasmid.fasta:virus.fasta\n".to_vec());
//! input_bytes.append(&mut b"2\tr651903\t\n".to_vec());
//!
//! let mut input: Cursor<Vec<u8>> = Cursor::new(input_bytes.clone());
//!
//! let mut output: Cursor<Vec<u8>> = Cursor::new(Vec::new());
//! let mut it = queries.into_iter();
//! let mut t_it = targets.into_iter();
//! let mut opts = EncodeOpts::default();
//! opts.accession = name;
//! opts.encode_query_names = true;
//! encode_from_read_to_write(Some(&mut t_it), Some(&mut it), &mut input, &mut output, opts).unwrap();
//! output.rewind();
//!
//! // Then, create a Decoder from `output` and retrieve the original data
//! let mut decoder = Decoder::new(&mut output).unwrap().map(|block| block.unwrap());
//!
//! let mut alns: Vec<PseudoAln> = Vec::new();
//! alns.extend(decoder); // Use Iterator to read all alignments from Decoder
//!
//! let expected = vec![
//! PseudoAln { ones: Some(vec![2]), ones_names: Some(vec!["virus.fasta".as_bytes().to_vec()]), query_id: Some(0), query_name: Some("r1".as_bytes().to_vec()) },
//! PseudoAln { ones: Some(vec![0, 2]), ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "virus.fasta".as_bytes().to_vec()]), query_id: Some(3), query_name: Some("r7543".as_bytes().to_vec()) },
//! PseudoAln { ones: Some(vec![0, 1, 2]), ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec(), "virus.fasta".as_bytes().to_vec()]), query_id: Some(4), query_name: Some("r16".as_bytes().to_vec()) },
//! PseudoAln { ones: Some(vec![]), ones_names: Some(vec![]), query_id: Some(2), query_name: Some("r651903".as_bytes().to_vec()) }
//! ];
//!
//! assert_eq!(alns, expected);
//! ```
//!
//! ### BitmapDecoder
//!
//! BitmapDecoder is useful for retrieving the alignments stored in some bitmap
//! that can be iterated to get the indexes of aligned bits in a flattened
//! representation of the pseudoalignment.
//!
//! ```rust
//! use ahda::headers::file::{FileHeader, FileFlags};
//! use ahda::headers::block::{BlockHeader, BlockFlags};
//! use ahda::decoder::bitmap_decoder::BitmapDecoder;
//! use ahda::PseudoAln;
//! use roaring::RoaringBitmap;
//!
//! let input = RoaringBitmap::from([2, 9, 11, 12, 13, 14]);
//! // `input` could alternatively be any u32 container, eg. a vector: vec![2_u32, 9, 11, 12, 13, 14]
//!
//! let file_header = FileHeader{
//! n_targets: 3_u32,
//! n_queries: 5_u32,
//! ahda_header: ahda::headers::file::build_ahda_header().unwrap(),
//! file_format: ahda::AhdaFormatVersion::V1_0_0.to_u8(),
//! metadata_compression: ahda::compression::MetadataCompression::default().to_u8(),
//! fields_present: 0,
//! bitmap_type: ahda::compression::BitmapType::Roaring32.to_u16(),
//! block_size: ((u32::MAX as u64) / (5_u64)).min(65537_u64) as u32,
//! flags_len: 44_u64,
//! };
//!
//! let mut bits_iter = input.iter().map(|x| x as u64); // BitmapDecoder expects u64 indices
//! let mut bitmap_decoder = BitmapDecoder::new(&mut bits_iter, file_header);
//!
//! assert_eq!(bitmap_decoder.next().unwrap(), PseudoAln { ones: Some(vec![2]), ones_names: None, query_id: Some(0), query_name: None });
//! assert_eq!(bitmap_decoder.next().unwrap(), PseudoAln { ones: Some(vec![0, 2]), ones_names: None, query_id: Some(3), query_name: None });
//! assert_eq!(bitmap_decoder.next().unwrap(), PseudoAln { ones: Some(vec![0, 1, 2]), ones_names: None, query_id: Some(4), query_name: None });
//!
//! assert_eq!(bitmap_decoder.next(), None); // Note that the PseudoAln with query_id: 2 is not included because it did not align against anything
//! ```
//!
pub mod bitmap_decoder;
use crate::PseudoAln;
use crate::headers::file::FileHeader;
use crate::headers::file::FileFlags;
use crate::headers::file::read_file_header;
use crate::headers::file::read_file_flags;
use crate::headers::block::BlockFlags;
use crate::headers::block::read_block_header;
use crate::compression::BitmapType;
use crate::compression::BitmapHolder;
use crate::compression::roaringwrapper::unpack_block_roaring;
use indexmap::IndexSet;
use roaring::RoaringBitmap;
use roaring::RoaringTreemap;
use std::collections::HashSet;
use std::io::Read;
type E = Box<dyn std::error::Error>;
use crate::errors::{
HeaderPromiseNotHonoured,
KeyNotFound,
MapDoesNotContainIndex,
PseudoAlnQueryIdIsNone,
PseudoAlnOnesIsNone,
PseudoAlnOnesNamesIsNone,
QueryIdsNotFilled,
};
/// Decoder for a [Read] containing the complete ahda file.
///
/// ## Usage
///
/// ### Read one record at a time
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
/// let decoder = Decoder::new(&mut data).unwrap();
///
/// let expected: Vec<PseudoAln> = vec![
/// PseudoAln { ones: Some(vec![0]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]), query_id: Some(0), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]) },
/// PseudoAln { ones: Some(vec![0]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]), query_id: Some(1), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50]) },
/// PseudoAln { ones: Some(vec![0, 1]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97], vec![112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97]]), query_id: Some(2), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51]) },
/// PseudoAln { ones: Some(vec![1]), ones_names: Some(vec![vec![112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97]]), query_id: Some(3), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51]) },
/// PseudoAln { ones: Some(vec![]), ones_names: Some(vec![]), query_id: Some(4), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]) },
/// ];
///
/// for (idx, record) in decoder.enumerate() {
/// let got = record.unwrap();
/// assert_eq!(got, expected[idx]);
/// }
/// ```
///
/// ### Read all available records
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
/// let decoder = Decoder::new(&mut data).unwrap();
///
/// let expected: Vec<PseudoAln> = vec![
/// PseudoAln { ones: Some(vec![0]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]), query_id: Some(0), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]) },
/// PseudoAln { ones: Some(vec![0]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]), query_id: Some(1), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50]) },
/// PseudoAln { ones: Some(vec![0, 1]), ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97], vec![112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97]]), query_id: Some(2), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51]) },
/// PseudoAln { ones: Some(vec![1]), ones_names: Some(vec![vec![112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97]]), query_id: Some(3), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51]) },
/// PseudoAln { ones: Some(vec![]), ones_names: Some(vec![]), query_id: Some(4), query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]) },
/// ];
///
/// let records: Vec<PseudoAln> = decoder.map(|record| record.unwrap()).collect();
///
/// assert_eq!(records, expected);
/// ```
///
pub struct Decoder<'a, R: Read> {
// Inputs
conn: &'a mut R,
header: FileHeader,
flags: FileFlags,
// Internals
block: Vec<PseudoAln>,
block_flags: Option<BlockFlags>,
block_index: usize,
bitmap: BitmapHolder,
q_ids: IndexSet<u32>,
q_names: Option<IndexSet<Vec<u8>>>,
t_names: IndexSet<Vec<u8>>,
// What values to fill in the records
fill_query_id: bool,
fill_query_name: bool,
fill_target_ids: bool,
fill_target_names: bool,
}
impl<'a, R: Read> Decoder<'a, R> {
/// Initialize a new Decoder from a [Read] containing a valid ahda file
///
/// ## Usage
///
/// ```rust
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
/// let decoder = Decoder::new(&mut data);
/// assert!(decoder.is_ok());
/// ```
pub fn new(
conn: &'a mut R,
) -> Result<Self, E> {
let header = read_file_header(conn)?;
let flags = read_file_flags(&header, conn)?;
let bitmap = match BitmapType::from_u16(header.bitmap_type)? {
BitmapType::Roaring32 => BitmapHolder::Roaring32(RoaringBitmap::new()),
BitmapType::Roaring64 => BitmapHolder::Roaring64(RoaringTreemap::new()),
};
Ok(Decoder{
block: Vec::with_capacity(header.block_size as usize),
q_ids: IndexSet::with_capacity(header.block_size as usize),
q_names: if header.promises_query_names() { Some(IndexSet::with_capacity(header.block_size as usize)) } else { None },
t_names: IndexSet::from_iter(flags.target_names.iter().cloned()),
conn,
header, flags,
block_index: 0_usize,
block_flags: None,
bitmap,
fill_query_id: true,
fill_query_name: true,
fill_target_ids: true,
fill_target_names: true,
})
}
/// Should Decoder fill the `query_id` field for each record?
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// decoder.fill_query_id(false);
///
/// let expected = PseudoAln {
/// ones: Some(vec![0]),
/// ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]),
/// query_id: None,
/// query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]),
/// };
///
/// let record: PseudoAln = decoder.next().unwrap().unwrap();
///
/// assert_eq!(record, expected);
/// ```
///
pub fn fill_query_id(
&mut self,
val: bool,
) {
self.fill_query_id = val;
}
/// Should Decoder fill the `query_name` field for each record?
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// decoder.fill_query_name(false);
///
/// let expected = PseudoAln {
/// ones: Some(vec![0]),
/// ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]),
/// query_id: Some(0),
/// query_name: None,
/// };
///
/// let record: PseudoAln = decoder.next().unwrap().unwrap();
///
/// assert_eq!(record, expected);
/// ```
///
pub fn fill_query_name(
&mut self,
val: bool,
) {
self.fill_query_name = val;
}
/// Should Decoder fill the `ones` field for each record?
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// decoder.fill_target_ids(false);
///
/// let expected = PseudoAln {
/// ones: None,
/// ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]),
/// query_id: Some(0),
/// query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]),
/// };
///
/// let record: PseudoAln = decoder.next().unwrap().unwrap();
///
/// assert_eq!(record, expected);
/// ```
///
pub fn fill_target_ids(
&mut self,
val: bool,
) {
self.fill_target_ids = val;
}
/// Should Decoder fill the `ones_names` field for each record?
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// decoder.fill_target_names(false);
///
/// let expected = PseudoAln {
/// ones: Some(vec![0]),
/// ones_names: None,
/// query_id: Some(0),
/// query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]),
/// };
///
/// let record: PseudoAln = decoder.next().unwrap().unwrap();
///
/// assert_eq!(record, expected);
/// ```
///
pub fn fill_target_names(
&mut self,
val: bool,
) {
self.fill_target_names = val;
}
}
impl<R: Read> Decoder<'_, R> {
/// Update internal state given a bitmap and block flags
fn alns_from_set_bits(
&mut self,
block_flags: &BlockFlags,
bitmap: &BitmapHolder
) -> Result<(), E> {
let mut it: Box<dyn Iterator<Item=u64>> = match bitmap {
BitmapHolder::Roaring32(bits) => {
let tmp = bits.iter().map(|x| x as u64);
Box::new(tmp)
},
BitmapHolder::Roaring64(bits) => {
let tmp = bits.iter();
Box::new(tmp)
},
};
let bitmap_decoder = bitmap_decoder::BitmapDecoder::new(&mut it, self.header.clone());
self.block = bitmap_decoder.collect();
if let Some(query_ids) = block_flags.query_ids.as_ref() {
let mut aligned_ids: Vec<u32> = Vec::with_capacity(self.block.len());
for record in &self.block {
match record.query_id {
Some(id) => aligned_ids.push(id),
None => return Err(Box::new(PseudoAlnQueryIdIsNone{}))
}
}
let seen: HashSet<u32> = HashSet::from_iter(aligned_ids);
self.block.extend(query_ids.iter().filter_map(|idx| {
if !seen.contains(idx) {
Some(PseudoAln{ ones_names: None, query_id: Some(*idx), ones: Some(vec![]), query_name: None })
} else {
None
}
}));
self.q_ids = IndexSet::from_iter(query_ids.iter().cloned());
} else {
return Err(Box::new(QueryIdsNotFilled{}))
}
self.q_names = if self.header.promises_query_names() {
if let Some(query_names) = block_flags.queries.as_ref() {
Some(IndexSet::from_iter(query_names.iter().cloned()))
} else {
return Err(Box::new(HeaderPromiseNotHonoured { promise: "`BlockFlags::queries`".to_string() } ))
}
} else {
None
};
Ok(())
}
/// Get the [FileHeader] decoded from the input.
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use ahda::headers::file::FileHeader;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
///
/// let expected = FileHeader {
/// ahda_header: [97_u8, 104, 100, 97, 0, 0],
/// file_format: 0,
/// metadata_compression: 1,
/// fields_present: 3,
/// n_targets: 2,
/// n_queries: 5,
/// bitmap_type: 0,
/// block_size: 65536,
/// flags_len: 51,
/// };
///
/// let got = decoder.file_header();
///
/// assert_eq!(got, &expected);
/// ```
///
pub fn file_header(
&self,
) -> &FileHeader {
&self.header
}
/// Get the [FileFlags] decoded from the input.
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use ahda::headers::file::FileFlags;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
///
/// let mut expected = FileFlags::default();
/// expected.query_name = vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54];
/// expected.target_names = vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97], vec![112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97]];
///
/// let got = decoder.file_flags();
///
/// assert_eq!(got, &expected);
/// ```
///
pub fn file_flags(
&self,
) -> &FileFlags {
&self.flags
}
/// Read next block and update internal state.
///
/// Use [Decoder::query_ids], [Decoder::query_names], [Decoder::records],
/// [Decoder::bitmap], and [Decoder::block_flags] to access the contents
/// after calling this.
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::compression::BitmapHolder;
/// use ahda::decoder::Decoder;
/// use ahda::headers::block::BlockFlags;
/// use ahda::headers::file::FileFlags;
/// use roaring::bitmap::RoaringBitmap;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_query_names = Some(vec![vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]]);
/// let query_names = decoder.query_names();
/// assert_eq!(query_names, expected_query_names);
///
/// let expected_query_ids = Some(vec![0, 1, 2, 3, 4]);
/// let query_ids = decoder.query_ids();
/// assert_eq!(query_ids, expected_query_ids);
///
/// let expected_block_flags = Some(BlockFlags {
/// queries: expected_query_names,
/// query_ids: expected_query_ids,
/// });
/// let block_flags = decoder.block_flags();
/// assert_eq!(block_flags, expected_block_flags.as_ref());
///
/// let expected_records = Some(vec![
/// PseudoAln { ones: Some(vec![0]), ones_names: None, query_id: Some(0), query_name: None },
/// PseudoAln { ones: Some(vec![0]), ones_names: None, query_id: Some(1), query_name: None },
/// PseudoAln { ones: Some(vec![0, 1]), ones_names: None, query_id: Some(2), query_name: None },
/// PseudoAln { ones: Some(vec![1]), ones_names: None, query_id: Some(3), query_name: None },
/// PseudoAln { ones: Some(vec![]), ones_names: None, query_id: Some(4), query_name: None },
/// ]);
/// let records = decoder.records();
/// assert_eq!(records, expected_records.as_ref());
///
/// let expected_bitmap = Some(BitmapHolder::Roaring32(RoaringBitmap::from_iter(vec![0, 2, 4, 5, 7])));
/// let bitmap = decoder.bitmap();
/// assert_eq!(bitmap, expected_bitmap.as_ref());
///
/// let ret = decoder.next_block();
/// assert!(ret.is_none());
/// ```
///
pub fn next_block(
&mut self,
) -> Option<Result<(), E>> {
self.block.clear();
self.q_ids.clear();
self.q_names = if self.header.promises_query_names() { Some(IndexSet::new()) } else { None };
match read_block_header(self.conn) {
Ok(block_header) => {
for i in 0..16 {
if (self.header.fields_present & (1 << i)) != 0 {
assert!((block_header.fields_present & (1 << i)) != 0);
}
}
let deflated_len: usize = match ((block_header.flags_len) + (block_header.block_len as u64)).try_into() {
Ok(len) => len,
Err(e) => return Some(Err(Box::new(e))),
};
let mut bytes: Vec<u8> = vec![0; deflated_len];
match self.conn.read_exact(&mut bytes) {
Ok(_) => (),
Err(e) => return Some(Err(Box::new(e))),
}
let (bitmap, block_flags) = match unpack_block_roaring(&bytes, &block_header) {
Ok(ret) => ret,
Err(e) => return Some(Err(e)),
};
match self.alns_from_set_bits(&block_flags, &bitmap) {
Ok(_) => {
self.bitmap = bitmap;
self.block_flags = Some(block_flags);
Some(Ok(()))
},
Err(e) => Some(Err(e)),
}
},
_ => None,
}
}
/// Get query ids in the current block, use [Decoder::next_block] to advance.
///
/// ## Usage
///
/// ```rust
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_query_ids = Some(vec![0, 1, 2, 3, 4]);
/// let query_ids = decoder.query_ids();
/// assert_eq!(query_ids, expected_query_ids);
/// ```
///
pub fn query_ids(
&self,
) -> Option<Vec<u32>> {
if self.block_flags.is_some() {
Some(self.q_ids.iter().cloned().collect())
} else {
None
}
}
/// Get query names in the current block if present, use [Decoder::next_block] to advance.
///
/// ## Usage
///
/// ```rust
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_query_names = Some(vec![vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]]);
/// let query_names = decoder.query_names();
/// assert_eq!(query_names, expected_query_names);
/// ```
///
pub fn query_names(
&self,
) -> Option<Vec<Vec<u8>>> {
Some(self.q_names.clone()?.iter().cloned().collect::<Vec<Vec<u8>>>())
}
/// Get records in the current block, use [Decoder::next_block] to advance.
///
/// ## Usage
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_records = Some(vec![
/// PseudoAln { ones: Some(vec![0]), ones_names: None, query_id: Some(0), query_name: None },
/// PseudoAln { ones: Some(vec![0]), ones_names: None, query_id: Some(1), query_name: None },
/// PseudoAln { ones: Some(vec![0, 1]), ones_names: None, query_id: Some(2), query_name: None },
/// PseudoAln { ones: Some(vec![1]), ones_names: None, query_id: Some(3), query_name: None },
/// PseudoAln { ones: Some(vec![]), ones_names: None, query_id: Some(4), query_name: None },
/// ]);
/// let records = decoder.records();
/// assert_eq!(records, expected_records.as_ref());
/// ```
///
pub fn records(
&self,
) -> Option<&Vec<PseudoAln>> {
if self.block_flags.is_some() {
Some(&self.block)
} else {
None
}
}
/// Get bitmap in the current block, use [Decoder::next_block] to advance.
///
/// ## Usage
///
/// ```rust
/// use ahda::compression::BitmapHolder;
/// use ahda::decoder::Decoder;
/// use roaring::bitmap::RoaringBitmap;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_bitmap = Some(BitmapHolder::Roaring32(RoaringBitmap::from_iter(vec![0, 2, 4, 5, 7])));
/// let bitmap = decoder.bitmap();
/// assert_eq!(bitmap, expected_bitmap.as_ref());
/// ```
///
pub fn bitmap(
&self,
) -> Option<&BitmapHolder> {
if self.block_flags.is_some() {
Some(&self.bitmap)
} else {
None
}
}
/// Get bitmap in the current block, use [Decoder::next_block] to advance.
///
/// ## Usage
///
/// ```rust
/// use ahda::decoder::Decoder;
/// use ahda::headers::block::BlockFlags;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// let ret = decoder.next_block().unwrap();
/// assert!(ret.is_ok());
///
/// let expected_query_names = Some(vec![vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]]);
/// let expected_query_ids = Some(vec![0, 1, 2, 3, 4]);
/// let expected_block_flags = Some(BlockFlags {
/// queries: Some(vec![vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 50], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 54, 53, 49, 57, 48, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 55, 53, 52, 51], vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49, 54]]),
/// query_ids: Some(vec![0, 1, 2, 3, 4]),
/// });
///
/// let block_flags = decoder.block_flags();
/// assert_eq!(block_flags, expected_block_flags.as_ref());
/// ```
///
pub fn block_flags(
&self,
) -> Option<&BlockFlags> {
self.block_flags.as_ref()
}
/// Update the fields in a PseudoAln based on what was requested.
///
/// This function is called from within [Decoder::next].
///
/// Use
/// - [Decoder::fill_query_id] to request filling the query index.
/// - [Decoder::fill_query_name] to request the query name.
/// - [Decoder::fill_target_ids] to request target indexes.
/// - [Decoder::fill_target_names] to request target names;
///
fn fill_record(
&self,
record: &mut PseudoAln,
) -> Result<(), E> {
if record.query_id.is_none() && self.fill_query_id {
// This branch shouldn't be reachable for a valid .ahda file
// Reason: query_id should always be filled
assert!(record.query_name.is_some());
assert!(self.q_names.is_some());
match &record.query_name {
Some(key) => {
match self.q_names.as_ref().unwrap().get_index_of(key) {
Some(query_id) => record.query_id = Some(query_id.try_into()?),
None => return Err(Box::new(KeyNotFound { key: key.clone(), map_name: "Decoder::q_names".to_string() })),
}
},
None => return Err(Box::new(PseudoAlnQueryIdIsNone{})),
}
}
if record.query_name.is_none() && self.fill_query_name {
let key: u32 = match record.query_id {
Some(query_id) => query_id,
None => return Err(Box::new(PseudoAlnQueryIdIsNone{})),
};
let index = match self.q_ids.get_index_of(&key) {
Some(index) => index,
None => return Err(Box::new(KeyNotFound { key: key.to_string().as_bytes().to_vec(), map_name: "Decoder::q_ids".to_string() }))
};
let query_name = if let Some(q_names) = &self.q_names {
match q_names.get_index(index) {
Some(q_name) => q_name.clone(),
None => return Err(Box::new(MapDoesNotContainIndex { index, map_name: "Decoder::q_names".to_string() }))
}
} else {
let mut new_name = self.flags.query_name.clone();
new_name.append(&mut vec![b'.']);
new_name.append(&mut (key + 1).to_string().as_bytes().to_vec());
new_name
};
record.query_name = Some(query_name);
}
if record.ones_names.is_none() && self.fill_target_names {
if let Some(ones) = record.ones.as_ref() {
let mut ones_names: Vec<Vec<u8>> = Vec::with_capacity(ones.len());
for target_idx in ones {
let key: usize = (*target_idx).try_into()?;
match self.t_names.get_index(key) {
Some(target_name) => ones_names.push(target_name.clone()),
None => return Err(Box::new(MapDoesNotContainIndex { index: key, map_name: "Decoder::t_names".to_string() })),
}
}
record.ones_names = Some(ones_names);
} else {
return Err(Box::new(PseudoAlnOnesIsNone{}))
}
}
if record.ones.is_none() && self.fill_target_ids {
if let Some(ones_names) = record.ones_names.as_ref() {
let mut ones: Vec<u32> = Vec::with_capacity(ones_names.len());
for target_name in ones_names {
match self.t_names.get_index_of(target_name) {
Some(target_idx) => ones.push(target_idx.try_into()?),
None => return Err(Box::new(KeyNotFound { key: target_name.clone(), map_name: "Decoder::t_names".to_string() })),
}
}
record.ones = Some(ones);
} else {
return Err(Box::new(PseudoAlnOnesNamesIsNone{}))
}
}
if !self.fill_query_id {
record.query_id = None;
}
if !self.fill_query_name {
record.query_name = None;
}
if !self.fill_target_ids {
record.ones = None;
}
if !self.fill_target_names {
record.ones_names = None;
}
Ok(())
}
}
impl<R: Read> Iterator for Decoder<'_, R> {
type Item = Result<PseudoAln, E>;
/// Get the next PseudoAln record
///
/// ## Usage
///
/// ### Get a record and fill all fields.
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
///
/// let expected_record = PseudoAln {
/// ones: Some(vec![0]),
/// ones_names: Some(vec![vec![99, 104, 114, 46, 102, 97, 115, 116, 97]]),
/// query_id: Some(0),
/// query_name: Some(vec![69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 46, 49]),
/// };
/// let ret = decoder.next();
/// assert!(ret.is_some());
///
/// let ret = ret.unwrap();
/// assert!(ret.is_ok());
///
/// let record = ret.unwrap();
/// assert_eq!(record, expected_record);
/// ```
///
/// ### Get a record without filling some fields
///
/// ```rust
/// use ahda::PseudoAln;
/// use ahda::decoder::Decoder;
/// use std::io::Cursor;
///
/// let bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
/// let mut data: Cursor<Vec<u8>> = Cursor::new(bytes);
///
/// let mut decoder = Decoder::new(&mut data).unwrap();
/// decoder.fill_target_names(false);
/// decoder.fill_query_name(false);
///
/// let expected_record = PseudoAln {
/// ones: Some(vec![0]),
/// ones_names: None,
/// query_id: Some(0),
/// query_name: None,
/// };
/// let ret = decoder.next();
/// assert!(ret.is_some());
///
/// let ret = ret.unwrap();
/// assert!(ret.is_ok());
///
/// let record = ret.unwrap();
/// assert_eq!(record, expected_record);
/// ```
fn next(
&mut self,
) -> Option<Self::Item> {
if self.block_index < self.block.len() {
self.block_index += 1;
let mut ret = self.block[self.block_index - 1].clone();
match self.fill_record(&mut ret) {
Ok(_) => Some(Ok(ret)),
Err(e) => Some(Err(e)),
}
} else {
match self.next_block()? {
Ok(_) => {
self.block_index = 0;
self.next()
},
Err(e) => Some(Err(e)),
}
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn file_header_and_file_flags() {
use super::Decoder;
use crate::AhdaFormatVersion;
use crate::compression::MetadataCompression;
use crate::compression::BitmapType;
use crate::headers::file::build_ahda_header;
use crate::headers::file::FileFlags;
use crate::headers::file::FileHeader;
use std::io::Cursor;
let compression = MetadataCompression::BincodeStandard;
let expected_flags = FileFlags { query_name: "ERR4035126".as_bytes().to_vec(), target_names: vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec()] };
let expected_header = FileHeader {
ahda_header: build_ahda_header().unwrap(),
file_format: AhdaFormatVersion::V1_0_0.to_u8(),
metadata_compression: compression.to_u8(),
fields_present: 0,
n_targets: 2_u32,
n_queries: 5_u32,
bitmap_type: BitmapType::Roaring32.to_u16(),
block_size: ((u32::MAX as u64) / (2_u64)).min(65536_u64) as u32,
flags_len: 36_u64,
};
let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 0, 10, 69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 2, 9, 99, 104, 114, 46, 102, 97, 115, 116, 97, 13, 112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97];
let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
let decoder = Decoder::new(&mut data).unwrap();
let got_header = decoder.file_header().clone();
let got_flags = decoder.file_flags().clone();
assert_eq!(got_header, expected_header);
assert_eq!(got_flags, expected_flags);
}
#[test]
fn next() {
use super::Decoder;
use crate::PseudoAln;
use std::io::Cursor;
let mut expected = vec![
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(1), ones: Some(vec![0]), query_name: Some("ERR4035126.2".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(0), ones: Some(vec![0]), query_name: Some("ERR4035126.1".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec()]), query_id: Some(2), ones: Some(vec![0, 1]), query_name: Some("ERR4035126.651903".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec![]), query_id: Some(4), ones: Some(vec![]), query_name: Some("ERR4035126.16".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["plasmid.fasta".as_bytes().to_vec()]), query_id: Some(3), ones: Some(vec![1]), query_name: Some("ERR4035126.7543".as_bytes().to_vec()) },
];
expected.sort_by_key(|x| *x.query_id.as_ref().unwrap());
let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 51, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 227, 114, 13, 10, 50, 49, 48, 54, 53, 52, 50, 99, 226, 76, 206, 40, 210, 75, 75, 44, 46, 73, 228, 45, 200, 73, 44, 206, 205, 76, 129, 240, 0, 66, 30, 44, 81, 36, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 49, 178, 50, 48, 50, 49, 179, 0, 0, 22, 232, 102, 239, 83, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
let mut decoder = Decoder::new(&mut data).unwrap();
for i in 0..expected.len() {
let got = decoder.next().unwrap().unwrap();
assert_eq!(got, expected[i]);
}
assert!(decoder.next().is_none());
}
// #[test]
// fn next_block() {
// use super::Decoder;
// use crate::PseudoAln;
// use std::io::Cursor;
// let mut expected = vec![
// PseudoAln{ones_names: None, query_id: Some(1), ones: Some(vec![0]), query_name: None },
// PseudoAln{ones_names: None, query_id: Some(0), ones: Some(vec![0]), query_name: None },
// PseudoAln{ones_names: None, query_id: Some(2), ones: Some(vec![0, 1]), query_name: None },
// PseudoAln{ones_names: None, query_id: Some(4), ones: Some(vec![]), query_name: None },
// PseudoAln{ones_names: None, query_id: Some(3), ones: Some(vec![1]), query_name: None },
// ];
// expected.sort_by_key(|x| *x.query_id.as_ref().unwrap());
// let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 32, 78, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 1, 10, 69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 1, 2, 9, 99, 104, 114, 46, 102, 97, 115, 116, 97, 13, 112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97, 5, 0, 0, 0, 103, 0, 0, 0, 40, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 229, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 9, 34, 113, 204, 76, 13, 45, 13, 140, 249, 145, 68, 204, 77, 77, 140, 121, 145, 245, 154, 177, 50, 48, 50, 49, 179, 0, 0, 164, 198, 115, 218, 81, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 22, 6, 1, 48, 205, 196, 192, 194, 192, 202, 192, 206, 0, 0, 47, 109, 177, 38, 26, 0, 0, 0];
// let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
// let mut decoder = Decoder::new(&mut data);
// let mut got = decoder.next_block().unwrap();
// got.sort_by_key(|x| *x.query_id.as_ref().unwrap());
// assert_eq!(got, expected);
// }
#[test]
fn decode_three_blocks() {
use super::Decoder;
use crate::PseudoAln;
use std::io::Cursor;
let mut expected = vec![
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(1), ones: Some(vec![0]), query_name: Some("ERR4035126.2".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(0), ones: Some(vec![0]), query_name: Some("ERR4035126.1".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec()]), query_id: Some(2), ones: Some(vec![0, 1]), query_name: Some("ERR4035126.651903".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec![]), query_id: Some(4), ones: Some(vec![]), query_name: Some("ERR4035126.16".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["plasmid.fasta".as_bytes().to_vec()]), query_id: Some(3), ones: Some(vec![1]), query_name: Some("ERR4035126.7543".as_bytes().to_vec()) },
];
expected.sort_by_key(|x| *x.query_id.as_ref().unwrap());
let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 10, 69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 2, 9, 99, 104, 114, 46, 102, 97, 115, 116, 97, 13, 112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97, 2, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 226, 113, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 68, 230, 24, 49, 50, 49, 48, 2, 0, 26, 63, 239, 0, 32, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 48, 205, 196, 0, 0, 133, 36, 27, 152, 20, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 18, 116, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 51, 53, 180, 52, 48, 230, 69, 18, 49, 52, 99, 100, 98, 98, 1, 0, 148, 139, 255, 106, 38, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 6, 6, 6, 22, 6, 86, 6, 0, 21, 37, 56, 88, 20, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 100, 228, 119, 13, 10, 50, 49, 48, 54, 53, 52, 50, 211, 51, 55, 53, 49, 102, 100, 100, 6, 0, 66, 122, 30, 150, 21, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 128, 0, 1, 6, 6, 6, 118, 6, 0, 71, 48, 17, 238, 18, 0, 0, 0];
let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
let decoder = Decoder::new(&mut data).unwrap();
let mut got: Vec<PseudoAln> = Vec::new();
got.extend(decoder.map(|block| block.unwrap()));
got.sort_by_key(|x| *x.query_id.as_ref().unwrap());
assert_eq!(got, expected);
}
#[test]
fn decode_three_blocks_without_query_names() {
use super::Decoder;
use crate::PseudoAln;
use std::io::Cursor;
let mut expected = vec![
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(1), ones: Some(vec![0]), query_name: None },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(0), ones: Some(vec![0]), query_name: None },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec()]), query_id: Some(2), ones: Some(vec![0, 1]), query_name: None },
PseudoAln{ones_names: Some(vec![]), query_id: Some(4), ones: Some(vec![]), query_name: None },
PseudoAln{ones_names: Some(vec!["plasmid.fasta".as_bytes().to_vec()]), query_id: Some(3), ones: Some(vec![1]), query_name: None },
];
expected.sort_by_key(|x| *x.query_id.as_ref().unwrap());
let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 10, 69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 2, 9, 99, 104, 114, 46, 102, 97, 115, 116, 97, 13, 112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97, 2, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 98, 96, 4, 0, 128, 116, 29, 10, 5, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 48, 205, 196, 0, 0, 133, 36, 27, 152, 20, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 98, 98, 1, 0, 141, 226, 65, 72, 5, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 6, 6, 6, 22, 6, 86, 6, 0, 21, 37, 56, 88, 20, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 100, 6, 0, 208, 213, 148, 160, 4, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 128, 0, 1, 6, 6, 6, 118, 6, 0, 71, 48, 17, 238, 18, 0, 0, 0];
let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
let mut decoder = Decoder::new(&mut data).unwrap();
decoder.fill_query_name(false);
let mut got: Vec<PseudoAln> = Vec::new();
got.extend(decoder.map(|block| block.unwrap()));
got.sort_by_key(|x| *x.query_id.as_ref().unwrap());
assert_eq!(got, expected);
}
#[test]
fn decode_three_blocks_without_query_names_and_rename() {
use super::Decoder;
use crate::PseudoAln;
use std::io::Cursor;
let mut expected = vec![
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(1), ones: Some(vec![0]), query_name: Some("ERR4035126.2".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec()]), query_id: Some(0), ones: Some(vec![0]), query_name: Some("ERR4035126.1".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["chr.fasta".as_bytes().to_vec(), "plasmid.fasta".as_bytes().to_vec()]), query_id: Some(2), ones: Some(vec![0, 1]), query_name: Some("ERR4035126.3".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec![]), query_id: Some(4), ones: Some(vec![]), query_name: Some("ERR4035126.5".as_bytes().to_vec()) },
PseudoAln{ones_names: Some(vec!["plasmid.fasta".as_bytes().to_vec()]), query_id: Some(3), ones: Some(vec![1]), query_name: Some("ERR4035126.4".as_bytes().to_vec()) },
];
expected.sort_by_key(|x| *x.query_id.as_ref().unwrap());
let data_bytes: Vec<u8> = vec![97, 104, 100, 97, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 10, 69, 82, 82, 52, 48, 51, 53, 49, 50, 54, 2, 9, 99, 104, 114, 46, 102, 97, 115, 116, 97, 13, 112, 108, 97, 115, 109, 105, 100, 46, 102, 97, 115, 116, 97, 2, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 98, 96, 4, 0, 128, 116, 29, 10, 5, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 48, 205, 196, 0, 0, 133, 36, 27, 152, 20, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 98, 98, 1, 0, 141, 226, 65, 72, 5, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 0, 1, 70, 6, 1, 6, 6, 6, 22, 6, 86, 6, 0, 21, 37, 56, 88, 20, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 99, 96, 100, 100, 6, 0, 208, 213, 148, 160, 4, 0, 0, 0, 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 179, 50, 96, 96, 96, 100, 128, 0, 1, 6, 6, 6, 118, 6, 0, 71, 48, 17, 238, 18, 0, 0, 0];
let mut data: Cursor<Vec<u8>> = Cursor::new(data_bytes);
let mut decoder = Decoder::new(&mut data).unwrap();
decoder.fill_query_name(true);
let mut got: Vec<PseudoAln> = Vec::new();
got.extend(decoder.map(|block| block.unwrap()));
got.sort_by_key(|x| *x.query_id.as_ref().unwrap());
assert_eq!(got, expected);
}
}