sorted_hlist/
lib.rs

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