tola_caps/primitives/
stream.rs

1//! Hash stream types for capability routing.
2//!
3//! Provides infinite nibble streams and Peano numbers for depth tracking.
4
5use core::marker::PhantomData;
6use super::nibble::Nibble;
7
8// =============================================================================
9// Hash Stream trait
10// =============================================================================
11
12/// Infinite stream of nibbles via recursive type
13pub trait HashStream: 'static {
14    type Head: Nibble;
15    type Tail: HashStream;
16}
17
18/// Helper to access stream at depth D
19pub trait GetTail<D> {
20    type Out: HashStream;
21}
22
23impl<H: HashStream> GetTail<Z> for H {
24    type Out = Self;
25}
26
27impl<H: HashStream, D> GetTail<S<D>> for H
28where
29    H::Tail: GetTail<D>,
30{
31    type Out = <H::Tail as GetTail<D>>::Out;
32}
33
34// =============================================================================
35// Stream implementations
36// =============================================================================
37
38/// Constant stream: N, N, N, N, ...
39pub struct ConstStream<N>(PhantomData<N>);
40
41impl<N: Nibble + 'static> HashStream for ConstStream<N> {
42    type Head = N;
43    type Tail = ConstStream<N>;
44}
45
46/// Alternating stream: A, B, A, B, ...
47pub struct AltStream<A, B>(PhantomData<(A, B)>);
48
49impl<A: Nibble + 'static, B: Nibble + 'static> HashStream for AltStream<A, B> {
50    type Head = A;
51    type Tail = AltStream<B, A>;
52}
53
54/// Cons cell for explicit streams
55pub struct Cons<H, T>(PhantomData<(H, T)>);
56
57impl<H: Nibble + 'static, T: HashStream> HashStream for Cons<H, T> {
58    type Head = H;
59    type Tail = T;
60}
61
62// =============================================================================
63// Peano Numbers
64// =============================================================================
65
66/// Peano number trait
67pub trait Peano {}
68
69/// Zero (base case)
70pub struct Z;
71impl Peano for Z {}
72
73/// Successor (S<N> = N + 1)
74pub struct S<N>(PhantomData<N>);
75impl<N: Peano> Peano for S<N> {}
76
77// Generate D0..D64 using proc-macro
78macros::peano!(64);
79
80/// Default max depth for collision resolution (16 nibbles = 64 bits)
81pub type DefaultMaxDepth = D16;
82
83// =============================================================================
84// Stream comparison
85// =============================================================================
86
87use super::bool::{Bool, Present, Absent};
88
89/// Compare two hash streams up to a depth limit
90pub trait StreamEq<Other: HashStream, Limit> {
91    type Out: Bool;
92}
93
94impl<A: HashStream, B: HashStream> StreamEq<B, Z> for A {
95    type Out = Present;
96}
97
98impl<A, B, L> StreamEq<B, S<L>> for A
99where
100    A: HashStream,
101    B: HashStream,
102    A::Head: super::nibble::NibbleEq<B::Head>,
103    <A::Head as super::nibble::NibbleEq<B::Head>>::Out: StreamEqDispatch<A::Tail, B::Tail, L>,
104{
105    type Out = <<A::Head as super::nibble::NibbleEq<B::Head>>::Out as StreamEqDispatch<A::Tail, B::Tail, L>>::Out;
106}
107
108pub trait StreamEqDispatch<TailA, TailB, Limit> {
109    type Out: Bool;
110}
111
112impl<TailA, TailB, L> StreamEqDispatch<TailA, TailB, L> for Absent {
113    type Out = Absent;
114}
115
116impl<TailA, TailB, L> StreamEqDispatch<TailA, TailB, L> for Present
117where
118    TailA: HashStream + StreamEq<TailB, L>,
119    TailB: HashStream,
120{
121    type Out = <TailA as StreamEq<TailB, L>>::Out;
122}
123
124// =============================================================================
125// Stream Intersection (Bitwise AND) - DISABLED: causes infinite compilation
126// =============================================================================
127
128// NOTE: StreamAnd is disabled because it has no depth limit and will cause
129// infinite compilation when used with cyclic streams like HashStream16.
130// If you need this functionality, add a depth limit parameter.
131
132/*
133/// Compute the bitwise AND of two capability streams.
134pub trait StreamAnd<Other: HashStream>: HashStream {
135    type Out: HashStream;
136}
137
138impl<A, B> StreamAnd<B> for A
139where
140    A: HashStream,
141    B: HashStream,
142    A::Head: super::nibble::HexAnd<B::Head>,
143    A::Tail: StreamAnd<B::Tail>,
144{
145    type Out = Cons<
146        <A::Head as super::nibble::HexAnd<B::Head>>::Out,
147        <A::Tail as StreamAnd<B::Tail>>::Out
148    >;
149}
150*/
151
152// =============================================================================
153// Const-to-Stream conversion (Stable Rust approach)
154// =============================================================================
155
156use super::nibble::{X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, XA, XB, XC, XD, XE, XF};
157
158/// Trait to select nibble type from const value
159pub trait SelectNibble<const N: u8> {
160    type Out: Nibble;
161}
162
163macro_rules! impl_select_nibble {
164    ($($val:literal => $nib:ident),* $(,)?) => {
165        $(
166            impl SelectNibble<$val> for () {
167                type Out = $nib;
168            }
169        )*
170    };
171}
172
173impl_select_nibble!(
174    0 => X0, 1 => X1, 2 => X2, 3 => X3,
175    4 => X4, 5 => X5, 6 => X6, 7 => X7,
176    8 => X8, 9 => X9, 10 => XA, 11 => XB,
177    12 => XC, 13 => XD, 14 => XE, 15 => XF,
178);
179
180/// Build a hash stream from 16 const nibble values (for 64-bit hash)
181/// Usage: HashStream16<{n0}, {n1}, ..., {n15}>
182pub struct HashStream16<
183    const N0: u8, const N1: u8, const N2: u8, const N3: u8,
184    const N4: u8, const N5: u8, const N6: u8, const N7: u8,
185    const N8: u8, const N9: u8, const N10: u8, const N11: u8,
186    const N12: u8, const N13: u8, const N14: u8, const N15: u8,
187>(PhantomData<()>);
188
189impl<
190    const N0: u8, const N1: u8, const N2: u8, const N3: u8,
191    const N4: u8, const N5: u8, const N6: u8, const N7: u8,
192    const N8: u8, const N9: u8, const N10: u8, const N11: u8,
193    const N12: u8, const N13: u8, const N14: u8, const N15: u8,
194> HashStream for HashStream16<N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15>
195where
196    (): SelectNibble<N0> + SelectNibble<N1> + SelectNibble<N2> + SelectNibble<N3>
197      + SelectNibble<N4> + SelectNibble<N5> + SelectNibble<N6> + SelectNibble<N7>
198      + SelectNibble<N8> + SelectNibble<N9> + SelectNibble<N10> + SelectNibble<N11>
199      + SelectNibble<N12> + SelectNibble<N13> + SelectNibble<N14> + SelectNibble<N15>,
200{
201    type Head = <() as SelectNibble<N0>>::Out;
202    type Tail = HashStream16<N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N0>;
203}
204
205// =============================================================================
206// ByteStream128 - Disabled (requires nightly features for proper streaming)
207// =============================================================================
208//
209// ByteStream128 with 64 nibble params would provide zero-collision identity,
210// but implementing proper Tail rotation requires either:
211// 1. generic_const_exprs (nightly)
212// 2. Specialization (nightly)
213// 3. Generating 64 wrapper types with complex dependency chains
214//
215// For now, we use HashStream16 (64-bit hash) which has negligible collision
216// probability in practice, and any collision results in safe compilation failure.