1use std::{cmp, ops::Range};
21
22use num::{NumCast, PrimInt};
23use rand::Rng;
24
25use super::{Hash, HASH_LEN};
26
27#[macro_export]
28macro_rules! max {
30 ($x:expr) => ($x);
31 ($x:expr, $($e:expr),+) => (cmp::max($x, max!($($e),+)));
32}
33
34#[macro_export]
35macro_rules! min {
37 ($x:expr) => ($x);
38 ($x:expr, $($e:expr),+) => (cmp::min($x, min!($($e),+)));
39}
40
41pub fn cast<T: NumCast, U: NumCast>(n: T) -> U {
43 NumCast::from(n).expect("cast(): Numcast")
44}
45
46pub fn random_byte() -> u8 {
48 rand::random::<u8>()
49}
50
51pub fn random_bytes(n: usize) -> Vec<u8> {
53 (0..n).map(|_| random_byte()).collect()
54}
55
56pub fn random_hash() -> Hash {
58 slice_to_hash(&random_bytes(HASH_LEN))
59}
60
61pub fn random_hashes(n: usize) -> Vec<Hash> {
63 (0..n).map(|_| random_hash()).collect()
64}
65
66pub fn slice_to_hash(slice: &[u8]) -> Hash {
68 let mut hash = [0x00; HASH_LEN];
69 hash.copy_from_slice(slice);
70 hash
71}
72
73pub fn shuffle<T: Clone>(slice: &mut [T]) {
75 let mut rng = rand::thread_rng();
76 let s = slice.len();
77 (0..s).for_each(|i| {
78 let q = rng.gen_range(0..s);
79 slice.swap(i, q);
80 });
81}
82
83pub fn get_sorted_indices<T>(slice: &[T], reverse: bool) -> Vec<usize>
85where
86 T: Clone + cmp::Ord,
87{
88 let mut t: Vec<_> = slice.iter().enumerate().collect();
89
90 if reverse {
91 t.sort_unstable_by(|(_, a), (_, b)| b.cmp(a));
92 } else {
93 t.sort_unstable_by(|(_, a), (_, b)| a.cmp(b));
94 }
95
96 t.iter().map(|(i, _)| *i).collect()
97}
98
99pub fn len_lcp<T>(a: &[u8], m: &Range<T>, b: &[u8], n: &Range<T>) -> T
101where
102 T: PrimInt + NumCast,
103 Range<T>: Iterator<Item = T>,
104{
105 let count = (cast(0)..min!(m.end - m.start, n.end - n.start))
106 .take_while(|&i| bit(a, m.start + i) == bit(b, n.start + i))
107 .count();
108 cast(count)
109}
110
111static BIT_MASKS: [u8; 8] = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01];
112
113#[inline]
115pub fn bit<T: PrimInt + NumCast>(bytes: &[u8], i: T) -> bool {
116 let i_usize = i.to_usize().unwrap();
117 let q = i_usize >> 3;
118 let r = i_usize & 7;
119 if q >= bytes.len() {
120 return false;
121 }
122 bytes[q] & BIT_MASKS[r] != 0
123}
124
125pub fn nbytes_across<T: PrimInt + NumCast>(start: T, end: T) -> T {
127 let eight = cast(8);
128 let bits = end - (start - start % eight);
129 (bits + eight - T::one()) / eight
130}
131
132pub fn bytes_to_int<T: PrimInt + NumCast>(bytes: &[u8]) -> T {
134 let l = bytes.len();
135 let sum = (0..l).fold(0, |sum, i| sum + (1 << ((l - i - 1) * 8)) * bytes[i] as usize);
136 cast(sum)
137}
138
139pub fn int_to_bytes(number: u64) -> Vec<u8> {
141 match number {
142 0 => vec![0x00],
143 _ => number.to_be_bytes().iter().skip_while(|&x| *x == 0x00).copied().collect(),
144 }
145}
146
147pub fn bits_to_usize(bits: &[bool]) -> usize {
149 let l = bits.len();
150 (0..l).fold(0, |sum, i| sum + ((bits[i] as usize) << (l - 1 - i)))
151}
152
153pub fn bytes_to_bits(bytes: &[u8]) -> Vec<bool> {
155 bytes_to_slicebit(bytes, &(0..bytes.len() * 8))
156}
157
158pub fn bytes_to_slicebit<T>(bytes: &[u8], range: &Range<T>) -> Vec<bool>
160where
161 T: PrimInt + NumCast,
162 Range<T>: Iterator<Item = T>,
163{
164 range.clone().map(|x| bit(bytes, x)).collect()
165}
166
167pub fn bits_to_bytes(bits: &[bool]) -> Vec<u8> {
169 bits.rchunks(8).rev().map(|v| bits_to_usize(v) as u8).collect()
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175 #[test]
176 fn test_bit() {
177 let bytes = [0x73, 0x6f, 0x66, 0x69, 0x61];
178 assert!(bit(&bytes, 10));
179 assert!(!bit(&bytes, 20));
180 assert!(!bit(&bytes, 30));
181 }
182
183 #[test]
184 fn test_nbyte_across() {
185 assert_eq!(nbytes_across(0, 8), 1);
186 assert_eq!(nbytes_across(1, 7), 1);
187 assert_eq!(nbytes_across(5, 9), 2);
188 assert_eq!(nbytes_across(9, 16), 1);
189 assert_eq!(nbytes_across(7, 19), 3);
190 }
191
192 #[test]
193 fn test_bytes_to_int() {
194 let number: usize = bytes_to_int(&[0x73, 0x6f, 0x66, 0x69, 0x61]);
195 assert_eq!(number, 495790221665usize);
196 }
197
198 #[test]
199 fn test_usize_to_bytes() {
200 assert_eq!(int_to_bytes(495790221665u64), [0x73, 0x6f, 0x66, 0x69, 0x61]);
201 }
202
203 #[test]
204 fn test_bytes_to_bits() {
205 assert_eq!(
206 bytes_to_bits(&[0x33, 0x33]),
207 [
208 false, false, true, true, false, false, true, true, false, false, true, true,
209 false, false, true, true,
210 ]
211 );
212 }
213
214 #[test]
215 fn test_bits_to_bytes() {
216 let bits = [
217 false, false, true, true, false, false, true, true, false, false, true, true, false,
218 false, true, true,
219 ];
220 assert_eq!(bits_to_bytes(&bits), [0x33, 0x33]);
221 }
222
223 #[test]
224 fn test_bits_to_usize() {
225 assert_eq!(
226 bits_to_usize(&[
227 false, false, true, true, false, false, true, true, false, false, true, true,
228 false, false, true, true,
229 ]),
230 13107usize
231 );
232 }
233
234 #[test]
235 fn test_len_lcp() {
236 let sofia = [0x73, 0x6f, 0x66, 0x69, 0x61];
237 let maria = [0x6d, 0x61, 0x72, 0x69, 0x61];
238 assert_eq!(len_lcp(&sofia, &(0..3), &maria, &(0..3)), 3);
239 assert_eq!(len_lcp(&sofia, &(0..3), &maria, &(5..9)), 0);
240 assert_eq!(len_lcp(&sofia, &(2..9), &maria, &(18..30)), 5);
241 assert_eq!(len_lcp(&sofia, &(20..30), &maria, &(3..15)), 4);
242 }
243}