1pub struct Zero;
2pub struct Succ<N>(std::marker::PhantomData<N>);
3
4pub trait Equal<N1, N2> {}
5impl Equal<Zero, Zero> for () {}
6impl<N1, N2> Equal<Succ<N1>, Succ<N2>> for () where (): Equal<N1, N2> {}
7
8pub trait IsNumber {}
9impl IsNumber for Zero {}
10impl<N> IsNumber for Succ<N> where N: IsNumber {}
11
12pub trait GreaterThanOrEqual<N1, N2> {}
13impl GreaterThanOrEqual<Zero, Zero> for () {}
14impl<N> GreaterThanOrEqual<Succ<N>, Zero> for () {}
15impl<N1, N2> GreaterThanOrEqual<Succ<N1>, Succ<N2>> for () where (): GreaterThanOrEqual<N1, N2> {}
16
17pub trait LessThan<N1, N2> {}
18impl<N> LessThan<Zero, Succ<N>> for () where N: IsNumber {}
19impl<N1, N2> LessThan<Succ<N1>, Succ<N2>> for () where (): LessThan<N1, N2> {}
20
21pub trait Max<N1, N2>
22where
23 N1: IsNumber,
24 N2: IsNumber,
25 Self::Output: IsNumber,
26{
27 type Output;
28}
29
30impl Max<Zero, Zero> for () {
31 type Output = Zero;
32}
33
34impl<N> Max<Succ<N>, Zero> for ()
35where
36 N: IsNumber,
37{
38 type Output = Succ<N>;
39}
40impl<N> Max<Zero, Succ<N>> for ()
41where
42 N: IsNumber,
43{
44 type Output = Succ<N>;
45}
46
47impl<N1, N2> Max<Succ<N1>, Succ<N2>> for ()
48where
49 N1: IsNumber,
50 N2: IsNumber,
51 (): Max<N1, N2>,
52{
53 type Output = Succ<<() as Max<N1, N2>>::Output>;
54}
55
56pub trait Min<N1, N2>
57where
58 N1: IsNumber,
59 N2: IsNumber,
60 Self::Output: IsNumber,
61{
62 type Output;
63}
64
65impl Min<Zero, Zero> for () {
66 type Output = Zero;
67}
68
69impl<N> Min<Succ<N>, Zero> for ()
70where
71 N: IsNumber,
72{
73 type Output = Zero;
74}
75impl<N> Min<Zero, Succ<N>> for ()
76where
77 N: IsNumber,
78{
79 type Output = Zero;
80}
81
82impl<N1, N2> Min<Succ<N1>, Succ<N2>> for ()
83where
84 N1: IsNumber,
85 N2: IsNumber,
86 (): Min<N1, N2>,
87{
88 type Output = Succ<<() as Min<N1, N2>>::Output>;
89}
90
91pub struct Here;
92pub struct Left<PrevDirection>(std::marker::PhantomData<PrevDirection>);
93pub struct Right<PrevDirection>(std::marker::PhantomData<PrevDirection>);