ahda 0.1.0

Pseudoalignment compression and conversion between formats.
Documentation
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
// 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.
//

//! Error types from the ahda library.

use crate::Format;

/// Not a valid [ahda library version](crate::AhdaVersion).
#[derive(Debug, Clone)]
pub struct AhdaVersionError;
impl std::fmt::Display for AhdaVersionError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Not a valid AhdaVersion")
    }
}
impl std::error::Error for AhdaVersionError {}

/// Not a valid [ahda file format version](crate::AhdaFormatVersion).
#[derive(Debug, Clone)]
pub struct AhdaFormatVersionErr;
impl std::fmt::Display for AhdaFormatVersionErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Not a valid AhdaFormatVersion")
    }
}
impl std::error::Error for AhdaFormatVersionErr {}

/// Binary data given to [check_ahda_header](crate::headers::file::check_ahda_header) does not start with the ahda header bytes.
///
/// ## Returned by
///
/// - [check_ahda_header](crate::headers::file::check_ahda_header).
///
#[derive(Debug, Clone)]
pub struct AhdaHeaderError;
impl std::fmt::Display for AhdaHeaderError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "bytes do not start with a valid ahda file header")
    }
}
impl std::error::Error for AhdaHeaderError {}

/// Set bits iterator given to [BitmapEncoder](crate::encoder::bitmap_encoder::BitmapEncoder) is not sorted.
///
/// ## Returned by
///
/// - [BitmapEncoder::next](crate::encoder::bitmap_encoder::BitmapEncoder::next).
///
#[derive(Debug, Clone)]
pub struct SetBitsIteratorNotSorted;
impl std::fmt::Display for SetBitsIteratorNotSorted {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "`set_bits` iterator given to BitmapEncoder::new() (argument #1) must be sorted.")
    }
}
impl std::error::Error for SetBitsIteratorNotSorted {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a Themisto plain text line.
#[derive(Debug, Clone)]
pub struct ThemistoPrinterError;
impl std::fmt::Display for ThemistoPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for ThemistoPrinterError {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a SAM plain text line.
#[derive(Debug, Clone)]
pub struct SamPrinterError;
impl std::fmt::Display for SamPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for SamPrinterError {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a Fulgor plain text line.
#[derive(Debug, Clone)]
pub struct FulgorPrinterError;
impl std::fmt::Display for FulgorPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for FulgorPrinterError {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a ahda .tsv plain text line.
#[derive(Debug, Clone)]
pub struct AhdaTSVPrinterError;
impl std::fmt::Display for AhdaTSVPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for AhdaTSVPrinterError {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a Bifrost plain text line.
#[derive(Debug, Clone)]
pub struct BifrostPrinterError;
impl std::fmt::Display for BifrostPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for BifrostPrinterError {}

/// Could not format [PseudoAln](crate::PseudoAln)(crate::PseudoAln) as a Metagraph plain text line.
#[derive(Debug, Clone)]
pub struct MetagraphPrinterError;
impl std::fmt::Display for MetagraphPrinterError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for MetagraphPrinterError {}

/// [Format::from_bytes] did not recognize the input format given to [Parser](crate::parser::Parser).
#[derive(Debug, Clone)]
pub struct UnrecognizedInputFormatErr;
impl std::fmt::Display for UnrecognizedInputFormatErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Unrecognized input format.")
    }
}
impl std::error::Error for UnrecognizedInputFormatErr {}

/// [Format::from_bytes] found a valid input format to [Parser](crate::parser::Parser) but could not confirm it with certainty.
#[derive(Debug, Clone)]
pub struct AmbiguousInputFormatErr;
impl std::fmt::Display for AmbiguousInputFormatErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Ambiguous input format.")
    }
}
impl std::error::Error for AmbiguousInputFormatErr {}

/// Plaintext data given to [Parser](crate::parser::Parser) is not in the expected format.
///
/// ## Returned by
///
/// - [Parser::read_header](crate::parser::Parser::read_header) (private method).
///
#[derive(Debug, Clone)]
pub struct CorruptedInputErr;
impl std::fmt::Display for CorruptedInputErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Corrupted input alignment data.")
    }
}
impl std::error::Error for CorruptedInputErr {}

/// Input format given to [Parser](crate::parser::Parser) requires supplying the target sequence names.
///
/// ## Returned by
///
/// - [Parser::new](crate::parser::Parser::new).
/// - [Parser::new_with_format](crate::parser::Parser::new_with_format).
///
#[derive(Debug, Clone)]
pub struct NeedTargetSequences {
    pub format: Format,
}
impl std::fmt::Display for NeedTargetSequences {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Detected input format `{}` requires supplying the target sequence names.", self.format)
    }
}
impl std::error::Error for NeedTargetSequences {}

/// Input format given to [Parser](crate::parser::Parser) requires supplying the query sequence names.
#[derive(Debug, Clone)]
pub struct NeedQueryNamesErr {
    pub format: Format,
}

impl std::fmt::Display for NeedQueryNamesErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Detected input format `{}` requires supplying the query sequence names.", self.format)
    }
}

impl std::error::Error for NeedQueryNamesErr {}

/// A [PseudoAln](crate::PseudoAln)(crate::PseudoAln) record given to encoder does not contain `query_id` and/or `ones`.
#[derive(Debug, Clone)]
pub struct EncodeError;
impl std::fmt::Display for EncodeError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "invalid input to encode")
    }
}
impl std::error::Error for EncodeError {}

/// Bifrost header line was not consumed before calling [read_bifrost](crate::parser::bifrost::read_bifrost).
#[derive(Debug, Clone)]
pub struct BifrostHeaderNotConsumedError;
impl std::fmt::Display for BifrostHeaderNotConsumedError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Bifrost header not consumed from input `Read`.")
    }
}
impl std::error::Error for BifrostHeaderNotConsumedError {}

/// Duplicated queries in files being concatenated.
#[derive(Debug, Clone)]
pub struct DuplicatedQueriesErr;
impl std::fmt::Display for DuplicatedQueriesErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Inputs contain duplicated query records, use a set operation to merge instead.")
    }
}
impl std::error::Error for DuplicatedQueriesErr {}

/// [BlockFlags](crate::headers::block::BlockFlags).query_ids is not filled.
///
/// ## Returned by
///
/// - [alns_from_set_bits](crate::decoder::Decoder::alns_from_set_bits). (private method)
///
#[derive(Debug, Clone)]
pub struct QueryIdsNotFilled;
impl std::fmt::Display for QueryIdsNotFilled {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `query_ids` in BlockFlags is not filled.")
    }
}
impl std::error::Error for QueryIdsNotFilled {}

/// [BlockFlags](crate::headers::block::BlockFlags).queries is not filled.
#[derive(Debug, Clone)]
pub struct QueryNamesNotFilled;
impl std::fmt::Display for QueryNamesNotFilled {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `queries` in BlockFlags is not filled.")
    }
}
impl std::error::Error for QueryNamesNotFilled {}

/// Duplicated queries in files being concatenated.
#[derive(Debug, Clone)]
pub struct IncompatibleFileHeadersErr;
impl std::fmt::Display for IncompatibleFileHeadersErr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Incompatible file headers.")
    }
}
impl std::error::Error for IncompatibleFileHeadersErr {}

/// Ahda .tsv header line was not consumed before calling [read_ahda_tsv](crate::parser::ahda_tsv::read_ahda_tsv).
#[derive(Debug, Clone)]
pub struct AhdaTSVHeaderNotConsumedError;
impl std::fmt::Display for AhdaTSVHeaderNotConsumedError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "AhdaTSV header not consumed from input `Read`.")
    }
}
impl std::error::Error for AhdaTSVHeaderNotConsumedError {}

/// Expected [PseudoAln](crate::PseudoAln).ones to be filled but it was empty
#[derive(Debug, Clone)]
pub struct PseudoAlnOnesIsEmpty;
impl std::fmt::Display for PseudoAlnOnesIsEmpty {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `ones` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnOnesIsEmpty {}

/// Expected [PseudoAln](crate::PseudoAln).ones to be filled but it was None.
///
/// ## Returned by
///
/// - [convert_to_roaring](crate::compression::roaringwrapper::convert_to_roaring).
/// - [Decoder::fill_record][crate::decoder::Decoder::fill_record] (private method).
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct PseudoAlnOnesIsNone;
impl std::fmt::Display for PseudoAlnOnesIsNone {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `ones` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnOnesIsNone {}

/// Expected [PseudoAln](crate::PseudoAln).ones_names to be filled but it was None
///
/// ## Returned by
///
/// - [Decoder::fill_record][crate::decoder::Decoder::fill_record] (private method).
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct PseudoAlnOnesNamesIsNone;
impl std::fmt::Display for PseudoAlnOnesNamesIsNone {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `ones_names` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnOnesNamesIsNone {}

/// Expected [PseudoAln](crate::PseudoAln).ones_names to be filled but it was empty
#[derive(Debug, Clone)]
pub struct PseudoAlnOnesNamesIsEmpty;
impl std::fmt::Display for PseudoAlnOnesNamesIsEmpty {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `ones_names` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnOnesNamesIsEmpty {}

/// Expected [PseudoAln](crate::PseudoAln).query_name to be filled but it was empty
#[derive(Debug, Clone)]
pub struct PseudoAlnQueryNameIsEmpty;
impl std::fmt::Display for PseudoAlnQueryNameIsEmpty {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `query_name` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnQueryNameIsEmpty {}

/// Expected [PseudoAln](crate::PseudoAln).query_name to be filled but it was None
///
/// ## Returned by
///
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct PseudoAlnQueryNameIsNone;
impl std::fmt::Display for PseudoAlnQueryNameIsNone {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `query_name` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnQueryNameIsNone {}

/// Expected [PseudoAln](crate::PseudoAln).query_id to be filled but it was empty
#[derive(Debug, Clone)]
pub struct PseudoAlnQueryIdIsEmpty;
impl std::fmt::Display for PseudoAlnQueryIdIsEmpty {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `query_id` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnQueryIdIsEmpty {}

/// Expected [PseudoAln](crate::PseudoAln).query_id to be filled but it was None.
///
/// ## Returned by
///
/// - [convert_to_roaring](crate::compression::roaringwrapper::convert_to_roaring).
/// - [alns_from_set_bits](crate::decoder::Decoder::alns_from_set_bits) (private method).
/// - [Decoder::fill_record][crate::decoder::Decoder::fill_record] (private method).
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct PseudoAlnQueryIdIsNone;
impl std::fmt::Display for PseudoAlnQueryIdIsNone {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Field `query_id` of PseudoAln is set but empty.")
    }
}
impl std::error::Error for PseudoAlnQueryIdIsNone {}

/// Key was not found in a map
///
/// ## Returned by
///
/// - [Decoder::fill_record][crate::decoder::Decoder::fill_record] (private method).
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct KeyNotFound {
    pub key: Vec<u8>,
    pub map_name: String,
}

impl std::fmt::Display for KeyNotFound {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Key {} was not found in map {}.", String::from_utf8(self.key.clone()).unwrap(), self.map_name)
    }
}
impl std::error::Error for KeyNotFound {}

/// Map contains less records than the requested index
///
/// ## Returned by
///
/// - [Decoder::fill_record][crate::decoder::Decoder::fill_record] (private method).
/// - [Parser::fill_record][crate::parser::Parser::fill_record] (private method).
///
#[derive(Debug, Clone)]
pub struct MapDoesNotContainIndex {
    pub index: usize,
    pub map_name: String,
}

impl std::fmt::Display for MapDoesNotContainIndex {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Map {} does not contain index {}.", self.map_name, self.index)
    }
}
impl std::error::Error for MapDoesNotContainIndex {}

/// A [FileHeader](crate::headers::file::FileHeader) or [BlockHeader](crate::headers::block::BlockHeader) promised a field is filled but it was not.
///
/// ## Returned by
///
/// - [pack_records](crate::compression::pack_records).
/// - [pack_block_roaring](crate::compression::roaringwrapper::pack_block_roaring).
/// - [alns_from_set_bits](crate::decoder::Decoder::alns_from_set_bits). (private method)
///
#[derive(Debug, Clone)]
pub struct HeaderPromiseNotHonoured {
    pub promise: String,
}
impl std::fmt::Display for HeaderPromiseNotHonoured {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "File or block header promised field {} in flags but it was None.", self.promise)
    }
}
impl std::error::Error for HeaderPromiseNotHonoured {}

/// Cannot convert between two values.
///
/// ## Returned by
///
/// - [BitmapType::from_u16](crate::compression::BitmapType::from_u16).
/// - [MetadataCompression::from_u16](crate::compression::MetadataCompression::from_u8).
///
#[derive(Debug, Clone)]
pub struct InvalidConversion {
    pub from: String,
    pub to: String,
}
impl std::fmt::Display for InvalidConversion {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "Invalid conversion of {} to {}.", self.from, self.to)
    }
}
impl std::error::Error for InvalidConversion {}