Skip to main content

sshash_lib/
lib.rs

1// SSHash: Sparse and Skew Hashing of k-mers
2//
3// A Rust implementation of the SSHash compressed k-mer dictionary,
4// providing efficient storage and querying of k-mer sets.
5
6#![doc = include_str!("../README.md")]
7#![warn(missing_docs)]
8
9pub mod constants;
10pub mod encoding;
11pub mod hasher;
12pub mod kmer;
13pub mod minimizer;
14pub mod mphf_config;
15pub mod offsets;
16pub mod minimizers_control_map;
17pub mod spectrum_preserving_string_set;
18pub mod sparse_and_skew_index;
19pub mod streaming_query;
20pub mod dictionary;
21pub mod builder;
22pub mod serialization;
23
24// Re-export common types at crate root 
25pub use kmer::{Kmer, Kmer21, Kmer31, Kmer63, KmerBits};
26pub use minimizer::{MinimizerInfo, MinimizerIterator};
27pub use minimizers_control_map::{MinimizersControlMap, MinimizersControlMapBuilder, BucketType};
28pub use streaming_query::{LookupResult, StreamingQuery};
29pub use dictionary::Dictionary;
30pub use builder::{BuildConfiguration, CfSegData, DictionaryBuilder, parse_cf_seg};
31
32/// Dispatch to the correct const generic `K` based on a runtime `k` value.
33///
34/// The const generic `K` determines both the storage type (`u64` for K ≤ 31,
35/// `u128` for K > 31) **and** the k-mer length used in operations like
36/// `reverse_complement()`, `from_str()`, and `decode_kmer()`.  Therefore `K`
37/// must always equal the actual k value, not merely the maximum for the
38/// storage class.
39///
40/// `k` must be an odd value in \[3, 63\]; these are the only values for which
41/// [`KmerBits`] is implemented.
42///
43/// # Usage
44///
45/// ```ignore
46/// use sshash_lib::dispatch_on_k;
47///
48/// dispatch_on_k!(k, K => {
49///     let kmer = Kmer::<K>::from_string(s)?;
50///     dict.lookup::<K>(&kmer)
51/// })
52/// ```
53///
54/// # Panics
55///
56/// Panics at runtime if `k` is even or outside the \[3, 63\] range.
57#[macro_export]
58macro_rules! dispatch_on_k {
59    ($k:expr, $K:ident => $body:expr) => {{
60        match $k {
61            3  => { const $K: usize = 3;  $body }
62            5  => { const $K: usize = 5;  $body }
63            7  => { const $K: usize = 7;  $body }
64            9  => { const $K: usize = 9;  $body }
65            11 => { const $K: usize = 11; $body }
66            13 => { const $K: usize = 13; $body }
67            15 => { const $K: usize = 15; $body }
68            17 => { const $K: usize = 17; $body }
69            19 => { const $K: usize = 19; $body }
70            21 => { const $K: usize = 21; $body }
71            23 => { const $K: usize = 23; $body }
72            25 => { const $K: usize = 25; $body }
73            27 => { const $K: usize = 27; $body }
74            29 => { const $K: usize = 29; $body }
75            31 => { const $K: usize = 31; $body }
76            33 => { const $K: usize = 33; $body }
77            35 => { const $K: usize = 35; $body }
78            37 => { const $K: usize = 37; $body }
79            39 => { const $K: usize = 39; $body }
80            41 => { const $K: usize = 41; $body }
81            43 => { const $K: usize = 43; $body }
82            45 => { const $K: usize = 45; $body }
83            47 => { const $K: usize = 47; $body }
84            49 => { const $K: usize = 49; $body }
85            51 => { const $K: usize = 51; $body }
86            53 => { const $K: usize = 53; $body }
87            55 => { const $K: usize = 55; $body }
88            57 => { const $K: usize = 57; $body }
89            59 => { const $K: usize = 59; $body }
90            61 => { const $K: usize = 61; $body }
91            63 => { const $K: usize = 63; $body }
92            other => panic!(
93                "Unsupported k value: {}. k must be an odd value between 3 and 63.",
94                other,
95            ),
96        }
97    }};
98}
99
100/// Version information
101pub fn version() -> (u8, u8, u8) {
102    constants::VERSION
103}
104
105#[cfg(test)]
106mod tests {
107    use super::*;
108
109    #[test]
110    fn test_version() {
111        let (major, minor, patch) = version();
112        assert_eq!(major, 0);
113        assert_eq!(minor, 1);
114        assert_eq!(patch, 0);
115    }
116}