1#![no_std]
2
3use typenum::{Cmp, Equal, Greater, Less};
4
5use core::marker::PhantomData;
6
7pub struct HNil;
8
9pub struct HCons<H, T>(PhantomData<(H, T)>);
10
11pub trait HList {}
12
13impl HList for HNil {}
14impl<H, T: HList> HList for HCons<H, T> {}
15
16#[macro_export]
17macro_rules! mk_hlist {
18 () => {
19 $crate::HNil
20 };
21 ($head:ty) => {
22 $crate::HCons<$head, $crate::HNil>
23 };
24 ($head:ty, $($tail:ty),+) => {
25 $crate::HCons<$head, $crate::mk_hlist!($($tail),+)>
26 };
27}
28
29pub trait SortedHList: HList {}
30
31impl SortedHList for HNil {}
32impl<H> SortedHList for HCons<H, HNil> {}
33
34pub trait LeOrEq {}
35impl LeOrEq for Equal {}
36impl LeOrEq for Less {}
37
38impl<H, HT, TT> SortedHList for HCons<H, HCons<HT, TT>>
39where
40 HCons<HT, TT>: SortedHList,
41 H: Cmp<HT>,
42 <H as Cmp<HT>>::Output: LeOrEq,
43{
44}
45
46pub trait NonEmptyHList: HList {}
47
48impl<H, T: HList> NonEmptyHList for HCons<H, T> {}
49
50pub trait Intersect<Other: SortedHList>: SortedHList {
51 type Output: SortedHList;
52}
53
54impl<H, T> Intersect<HNil> for HCons<H, T>
55where
56 HCons<H, T>: SortedHList,
57{
58 type Output = HNil;
59}
60
61impl<List: SortedHList> Intersect<List> for HNil {
62 type Output = HNil;
63}
64
65pub trait IntersectByOrder<Rhs: SortedHList, Ord>: SortedHList {
66 type Output: SortedHList;
67}
68
69impl<HA, TA, HB, TB> IntersectByOrder<HCons<HB, TB>, Less> for HCons<HA, TA>
70where
71 Self: SortedHList,
72 HCons<HB, TB>: SortedHList,
73 TA: Intersect<HCons<HB, TB>>,
74{
75 type Output = <TA as Intersect<HCons<HB, TB>>>::Output;
76}
77
78impl<HA, TA, HB, TB: SortedHList> IntersectByOrder<HCons<HB, TB>, Greater> for HCons<HA, TA>
79where
80 HCons<HA, TA>: SortedHList,
81 HCons<HB, TB>: SortedHList,
82 Self: Intersect<TB>,
83{
84 type Output = <Self as Intersect<TB>>::Output;
85}
86
87impl<HA, TA, HB, TB: SortedHList> IntersectByOrder<HCons<HB, TB>, Equal> for HCons<HA, TA>
88where
89 Self: SortedHList,
90 HCons<HB, TB>: SortedHList,
91 TA: Intersect<TB>,
92 HCons<HA, <TA as Intersect<TB>>::Output>: SortedHList,
93{
94 type Output = HCons<HA, <TA as Intersect<TB>>::Output>;
95}
96
97impl<HA, TA, HB, TB, Ordering> Intersect<HCons<HB, TB>> for HCons<HA, TA>
98where
99 HA: Cmp<HB, Output = Ordering>,
100 HCons<HA, TA>: IntersectByOrder<HCons<HB, TB>, Ordering>,
101 HCons<HB, TB>: SortedHList,
102{
103 type Output = <Self as IntersectByOrder<HCons<HB, TB>, Ordering>>::Output;
104}