solverforge_scoring/stream/
collection_extract.rs1pub trait CollectionExtract<S>: Send + Sync {
30 type Item;
32
33 fn extract<'s>(&self, s: &'s S) -> &'s [Self::Item];
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub enum ChangeSource {
39 Static,
40 Descriptor(usize),
41}
42
43pub trait TrackedCollectionExtract<S>: CollectionExtract<S> {
44 fn change_source(&self) -> ChangeSource;
45}
46
47pub trait FlattenExtract<P>: Send + Sync {
48 type Item;
49
50 fn extract<'s>(&self, parent: &'s P) -> &'s [Self::Item];
51}
52
53impl<S, A, F> CollectionExtract<S> for F
54where
55 F: for<'a> Fn(&'a S) -> &'a [A] + Send + Sync,
56{
57 type Item = A;
58
59 #[inline]
60 fn extract<'s>(&self, s: &'s S) -> &'s [A] {
61 self(s)
62 }
63}
64
65impl<P, B, F> FlattenExtract<P> for F
66where
67 F: for<'a> Fn(&'a P) -> &'a [B] + Send + Sync,
68{
69 type Item = B;
70
71 #[inline]
72 fn extract<'s>(&self, parent: &'s P) -> &'s [B] {
73 self(parent)
74 }
75}
76
77#[derive(Clone, Copy)]
78pub struct FlattenVecExtract<F>(pub F);
79
80impl<P, B, F> FlattenExtract<P> for FlattenVecExtract<F>
81where
82 F: for<'a> Fn(&'a P) -> &'a Vec<B> + Send + Sync,
83{
84 type Item = B;
85
86 #[inline]
87 fn extract<'s>(&self, parent: &'s P) -> &'s [B] {
88 (self.0)(parent).as_slice()
89 }
90}
91
92#[derive(Clone, Copy)]
93pub struct TrackedExtract<E> {
94 extractor: E,
95 change_source: ChangeSource,
96}
97
98impl<E> TrackedExtract<E> {
99 pub fn new(extractor: E, change_source: ChangeSource) -> Self {
100 Self {
101 extractor,
102 change_source,
103 }
104 }
105
106 pub fn extractor(&self) -> &E {
107 &self.extractor
108 }
109}
110
111impl<S, E> CollectionExtract<S> for TrackedExtract<E>
112where
113 E: CollectionExtract<S>,
114{
115 type Item = E::Item;
116
117 #[inline]
118 fn extract<'s>(&self, s: &'s S) -> &'s [Self::Item] {
119 self.extractor.extract(s)
120 }
121}
122
123impl<S, E> TrackedCollectionExtract<S> for TrackedExtract<E>
124where
125 E: CollectionExtract<S>,
126{
127 fn change_source(&self) -> ChangeSource {
128 self.change_source
129 }
130}
131
132pub struct VecExtract<F>(pub F);
137
138impl<S, A, F> CollectionExtract<S> for VecExtract<F>
139where
140 F: for<'a> Fn(&'a S) -> &'a Vec<A> + Send + Sync,
141{
142 type Item = A;
143
144 #[inline]
145 fn extract<'s>(&self, s: &'s S) -> &'s [A] {
146 (self.0)(s).as_slice()
147 }
148}
149
150pub fn vec<S, A, F>(f: F) -> VecExtract<F>
169where
170 F: for<'a> Fn(&'a S) -> &'a Vec<A> + Send + Sync,
171{
172 VecExtract(f)
173}
174
175pub fn tracked<E>(extractor: E, change_source: ChangeSource) -> TrackedExtract<E> {
176 TrackedExtract::new(extractor, change_source)
177}