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
|
use std::convert::TryInto;
use self::remainders::CalcRemainders;
mod remainders;
mod remainders_impl;
/// Converts an input to a different base (which fits in usize). Returns the digits starting at the most significant one.
pub(super) trait BaseConversion {
// return type is subject to change. Hopefully soon the math will be rewritten, so we can skip the Vec and IntoIter.
// will have to remain an ExactSizeIterator though.
fn convert_to_base(self, base : usize) -> std::iter::Rev<std::vec::IntoIter<usize>>;
}
impl<T, const N : usize> BaseConversion for T where T : ToI32Array<Output = [u32;N]>{
fn convert_to_base(self, base : usize) -> std::iter::Rev<std::vec::IntoIter<usize>> {
self.to_int_array().calc_remainders(base).collect::<Vec<_>>().into_iter().rev()
}
}
impl BaseConversion for [u8;16]{
fn convert_to_base(self, base : usize) -> std::iter::Rev<std::vec::IntoIter<usize>> {
u128::from_be_bytes(self).calc_remainders(base as u128).map(|ll| ll as usize).collect::<Vec<_>>().into_iter().rev()
}
}
// Rust 1.52 only has a very limited support for const generics. This means, we'll have to live with this not-too-constrained solution...
pub(super) trait ToI32Array {
type Output;
fn to_int_array(self) -> Self::Output;
}
//this could of course be done in a generic manner, but it's ugly without array_mut, which we don't have in Rust 1.52.
//Soo, pedestrian's approach :D
impl ToI32Array for [u8;20] {
type Output = [u32; 5];
fn to_int_array(self) -> [u32; 5] {
[
u32::from_be_bytes(self[0..4].try_into().unwrap()),
u32::from_be_bytes(self[4..8].try_into().unwrap()),
u32::from_be_bytes(self[8..12].try_into().unwrap()),
u32::from_be_bytes(self[12..16].try_into().unwrap()),
u32::from_be_bytes(self[16..20].try_into().unwrap()),
]
}
}
impl ToI32Array for [u8;32] {
type Output = [u32; 8];
fn to_int_array(self) -> [u32; 8] {
[
u32::from_be_bytes(self[0..4].try_into().unwrap()),
u32::from_be_bytes(self[4..8].try_into().unwrap()),
u32::from_be_bytes(self[8..12].try_into().unwrap()),
u32::from_be_bytes(self[12..16].try_into().unwrap()),
u32::from_be_bytes(self[16..20].try_into().unwrap()),
u32::from_be_bytes(self[20..24].try_into().unwrap()),
u32::from_be_bytes(self[24..28].try_into().unwrap()),
u32::from_be_bytes(self[28..32].try_into().unwrap()),
]
}
}
|