Skip to main content

object_rainbow/impls/
generic_array.rs

1use std::ops::Mul;
2
3use generic_array::sequence::{Flatten, GenericSequence};
4use typenum::{B0, B1, IsGreater, U0, U1};
5
6use crate::*;
7
8impl<T: InlineOutput, N: ArrayLength> ToOutput for GenericArray<T, N> {
9    fn to_output(&self, output: &mut impl Output) {
10        T::slice_to_output(self, output);
11    }
12}
13
14impl<T: InlineOutput, N: ArrayLength> InlineOutput for GenericArray<T, N> {}
15
16impl<T: ListHashes, N: ArrayLength> ListHashes for GenericArray<T, N> {
17    fn list_hashes(&self, f: &mut impl FnMut(Hash)) {
18        self.iter_list_hashes(f);
19    }
20}
21
22impl<T: Topological, N: ArrayLength> Topological for GenericArray<T, N> {
23    fn traverse(&self, visitor: &mut impl PointVisitor) {
24        self.iter_traverse(visitor);
25    }
26}
27
28impl<T: Tagged, N: ArrayLength> Tagged for GenericArray<T, N> {
29    const TAGS: Tags = T::TAGS;
30}
31
32impl<T: Size, N: ArrayLength> Size for GenericArray<T, N>
33where
34    N: Mul<T::Size, Output: Unsigned>,
35{
36    type Size = <N as Mul<T::Size>>::Output;
37}
38
39impl<T: ParseInline<I>, N: ArrayLength, I: ParseInput> Parse<I> for GenericArray<T, N> {
40    fn parse(input: I) -> crate::Result<Self> {
41        Self::parse_as_inline(input)
42    }
43}
44
45impl<T: ParseInline<I>, N: ArrayLength, I: ParseInput> ParseInline<I> for GenericArray<T, N> {
46    fn parse_inline(input: &mut I) -> crate::Result<Self> {
47        input.parse_generic_array()
48    }
49}
50
51impl<T: ByteOrd + InlineOutput, N: ArrayLength> ByteOrd for GenericArray<T, N> {
52    fn bytes_cmp(&self, other: &Self) -> Ordering {
53        self.iter_bytes_cmp(other)
54    }
55}
56
57pub trait WideNiche<T, N> {
58    type MnArray;
59}
60
61impl<T, N> WideNiche<T, N> for (B1, B1) {
62    type MnArray = NoNiche<ZeroNiche<U0>>;
63}
64
65pub struct RepeatNiche<M, N>(M, N);
66
67impl<M: Niche<NeedsTag = B1, Cut = B0>, N: ArrayLength, K: ArrayLength> Niche for RepeatNiche<M, N>
68where
69    M::N: Mul<N, Output = K>,
70{
71    type NeedsTag = B1;
72    type Cut = B0;
73    type N = K;
74    fn niche() -> GenericArray<u8, Self::N> {
75        GenericArray::<_, N>::repeat(M::niche()).flatten()
76    }
77    type Next = Self;
78}
79
80impl<T: MaybeHasNiche<MnArray: MnArray<MaybeNiche = M>>, N, M> WideNiche<T, N> for (B1, B0) {
81    type MnArray = NoNiche<RepeatNiche<M, N>>;
82}
83
84pub struct ForceCut<M>(M);
85
86impl<M: Niche<NeedsTag = B0>> Niche for ForceCut<M> {
87    type NeedsTag = B0;
88    type Cut = B1;
89    type N = M::N;
90    fn niche() -> GenericArray<u8, Self::N> {
91        M::niche()
92    }
93    type Next = ForceCut<M::Next>;
94}
95
96impl<T: MaybeHasNiche<MnArray: MnArray<MaybeNiche = M>>, N, B, M> WideNiche<T, N> for (B0, B) {
97    type MnArray = SomeNiche<ForceCut<M>>;
98}
99
100pub trait MoreThan1<T, N> {
101    type MnArray;
102}
103
104impl<
105    T: MaybeHasNiche<MnArray: MnArray<MaybeNiche: Niche<NeedsTag = NeedsTag, Cut = Cut>>>,
106    N,
107    NeedsTag,
108    Cut,
109> MoreThan1<T, N> for B1
110where
111    (NeedsTag, Cut): WideNiche<T, N>,
112{
113    type MnArray = <(NeedsTag, Cut) as WideNiche<T, N>>::MnArray;
114}
115
116impl<T: MaybeHasNiche, N> MoreThan1<T, N> for B0 {
117    type MnArray = T::MnArray;
118}
119
120pub trait MoreThan0<T, N> {
121    type MnArray;
122}
123
124impl<T, N: IsGreater<U1, Output = B>, B: MoreThan1<T, N>> MoreThan0<T, N> for B1 {
125    type MnArray = B::MnArray;
126}
127
128impl<T, N> MoreThan0<T, N> for B0 {
129    type MnArray = NoNiche<ZeroNoNiche<U0>>;
130}
131
132impl<T, N: ArrayLength + IsGreater<U0, Output = B>, B: MoreThan0<T, N>> MaybeHasNiche
133    for GenericArray<T, N>
134{
135    type MnArray = B::MnArray;
136}