graphrecords_query/element/
arity.rs1use crate::sealed::Sealed;
2use std::marker::PhantomData;
3
4pub type BoxedIterator<'a, T> = Box<dyn Iterator<Item = T> + 'a>;
5
6pub trait Arity: 'static {
7 type Container<'a, X: 'a>: 'a;
8 type AfterDrop: Arity;
9 type AfterOrderedExpansion: Arity;
10 type AfterUnorderedExpansion: Arity;
11
12 fn map_elements<'a, X: 'a, Y: 'a>(
13 container: Self::Container<'a, X>,
14 function: impl Fn(X) -> Y + 'a,
15 ) -> Self::Container<'a, Y>;
16
17 fn filter_map_elements<'a, X: 'a, Y: 'a>(
18 container: Self::Container<'a, X>,
19 function: impl Fn(X) -> Option<Y> + 'a,
20 ) -> <Self::AfterDrop as Arity>::Container<'a, Y>;
21
22 fn flat_map_ordered_elements<'a, X: 'a, Y: 'a>(
23 container: Self::Container<'a, X>,
24 function: impl Fn(X) -> Vec<Y> + 'a,
25 ) -> <Self::AfterOrderedExpansion as Arity>::Container<'a, Y>;
26
27 fn flat_map_unordered_elements<'a, X: 'a, Y: 'a>(
28 container: Self::Container<'a, X>,
29 function: impl Fn(X) -> Vec<Y> + 'a,
30 ) -> <Self::AfterUnorderedExpansion as Arity>::Container<'a, Y>;
31}
32
33pub trait OrderState: Sealed + 'static {}
34
35pub struct Ordered;
36pub struct Unordered;
37
38impl Sealed for Ordered {}
39impl Sealed for Unordered {}
40
41impl OrderState for Ordered {}
42
43impl OrderState for Unordered {}
44
45pub struct Multiple<O: OrderState>(PhantomData<O>);
46pub struct Single;
47pub struct Definite;
48
49impl<O: OrderState> Arity for Multiple<O> {
50 type AfterDrop = Self;
51 type AfterOrderedExpansion = Self;
52 type AfterUnorderedExpansion = Multiple<Unordered>;
53 type Container<'a, X: 'a> = BoxedIterator<'a, X>;
54
55 fn map_elements<'a, X: 'a, Y: 'a>(
56 container: Self::Container<'a, X>,
57 function: impl Fn(X) -> Y + 'a,
58 ) -> Self::Container<'a, Y> {
59 Box::new(container.map(function))
60 }
61
62 fn filter_map_elements<'a, X: 'a, Y: 'a>(
63 container: Self::Container<'a, X>,
64 function: impl Fn(X) -> Option<Y> + 'a,
65 ) -> <Self::AfterDrop as Arity>::Container<'a, Y> {
66 Box::new(container.filter_map(function))
67 }
68
69 fn flat_map_ordered_elements<'a, X: 'a, Y: 'a>(
70 container: Self::Container<'a, X>,
71 function: impl Fn(X) -> Vec<Y> + 'a,
72 ) -> <Self::AfterOrderedExpansion as Arity>::Container<'a, Y> {
73 Box::new(container.flat_map(function))
74 }
75
76 fn flat_map_unordered_elements<'a, X: 'a, Y: 'a>(
77 container: Self::Container<'a, X>,
78 function: impl Fn(X) -> Vec<Y> + 'a,
79 ) -> <Self::AfterUnorderedExpansion as Arity>::Container<'a, Y> {
80 Box::new(container.flat_map(function))
81 }
82}
83
84impl Arity for Single {
85 type AfterDrop = Self;
86 type AfterOrderedExpansion = Multiple<Ordered>;
87 type AfterUnorderedExpansion = Multiple<Unordered>;
88 type Container<'a, X: 'a> = Option<X>;
89
90 fn map_elements<'a, X: 'a, Y: 'a>(
91 container: Self::Container<'a, X>,
92 function: impl Fn(X) -> Y + 'a,
93 ) -> Self::Container<'a, Y> {
94 container.map(function)
95 }
96
97 fn filter_map_elements<'a, X: 'a, Y: 'a>(
98 container: Self::Container<'a, X>,
99 function: impl Fn(X) -> Option<Y> + 'a,
100 ) -> <Self::AfterDrop as Arity>::Container<'a, Y> {
101 container.and_then(function)
102 }
103
104 fn flat_map_ordered_elements<'a, X: 'a, Y: 'a>(
105 container: Self::Container<'a, X>,
106 function: impl Fn(X) -> Vec<Y> + 'a,
107 ) -> <Self::AfterOrderedExpansion as Arity>::Container<'a, Y> {
108 Box::new(container.into_iter().flat_map(function))
109 }
110
111 fn flat_map_unordered_elements<'a, X: 'a, Y: 'a>(
112 container: Self::Container<'a, X>,
113 function: impl Fn(X) -> Vec<Y> + 'a,
114 ) -> <Self::AfterUnorderedExpansion as Arity>::Container<'a, Y> {
115 Box::new(container.into_iter().flat_map(function))
116 }
117}
118
119impl Arity for Definite {
120 type AfterDrop = Single;
121 type AfterOrderedExpansion = Multiple<Ordered>;
122 type AfterUnorderedExpansion = Multiple<Unordered>;
123 type Container<'a, X: 'a> = X;
124
125 fn map_elements<'a, X: 'a, Y: 'a>(
126 container: Self::Container<'a, X>,
127 function: impl Fn(X) -> Y + 'a,
128 ) -> Self::Container<'a, Y> {
129 function(container)
130 }
131
132 fn filter_map_elements<'a, X: 'a, Y: 'a>(
133 container: Self::Container<'a, X>,
134 function: impl Fn(X) -> Option<Y> + 'a,
135 ) -> <Self::AfterDrop as Arity>::Container<'a, Y> {
136 function(container)
137 }
138
139 fn flat_map_ordered_elements<'a, X: 'a, Y: 'a>(
140 container: Self::Container<'a, X>,
141 function: impl Fn(X) -> Vec<Y> + 'a,
142 ) -> <Self::AfterOrderedExpansion as Arity>::Container<'a, Y> {
143 Box::new(function(container).into_iter())
144 }
145
146 fn flat_map_unordered_elements<'a, X: 'a, Y: 'a>(
147 container: Self::Container<'a, X>,
148 function: impl Fn(X) -> Vec<Y> + 'a,
149 ) -> <Self::AfterUnorderedExpansion as Arity>::Container<'a, Y> {
150 Box::new(function(container).into_iter())
151 }
152}