ordinal_map/ordinal/impls/
array.rs1use crate::array_builder::ArrayBuilder;
2use crate::Ordinal;
3
4impl<T: Ordinal, const N: usize> Ordinal for [T; N] {
5 const ORDINAL_SIZE: usize = {
6 let mut s = 1usize;
7 let mut i = 0;
8 while i < N {
9 s = s.checked_mul(T::ORDINAL_SIZE).unwrap();
10 i += 1;
11 }
12 s
13 };
14
15 fn ordinal(&self) -> usize {
16 let mut r = 0usize;
17 for v in self {
18 r = r.checked_mul(T::ORDINAL_SIZE).unwrap();
19 r += v.ordinal();
20 }
21 r
22 }
23
24 fn from_ordinal(ordinal: usize) -> Option<Self> {
25 let mut n = ordinal;
26 let mut array = ArrayBuilder::new();
27 for _ in 0..N {
28 let Some(i) = n.checked_rem(T::ORDINAL_SIZE) else {
29 return None;
30 };
31 array.push(T::from_ordinal(i).unwrap());
32 n /= T::ORDINAL_SIZE;
33 }
34 if n != 0 {
35 None
36 } else {
37 let mut array = array.finish();
38 array.reverse();
39 Some(array)
40 }
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use std::convert::Infallible;
47
48 use crate::tests::util::test_ordinal;
49
50 #[test]
51 fn test_array_of_empty() {
52 test_ordinal::<[Infallible; 0]>([[]]);
53 test_ordinal::<[Infallible; 1]>([]);
54 test_ordinal::<[Infallible; 2]>([]);
55 }
56
57 #[test]
58 fn test_array_0() {
59 test_ordinal::<[u16; 0]>([[]]);
60 }
61
62 #[test]
63 fn test_array_1() {
64 test_ordinal([[false], [true]]);
65 }
66
67 #[test]
68 fn test_array_2() {
69 test_ordinal([[false, false], [false, true], [true, false], [true, true]]);
70 test_ordinal([(false, false), (false, true), (true, false), (true, true)]);
72 }
73}