sorted_hlist/
lib.rs

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}