composable_indexes_core/
query_result.rs

1use std::num::Wrapping;
2
3use crate::Key;
4
5/// Trait for types that can be returned from queries.
6pub trait QueryResult {
7    type Resolved<T>;
8    fn map<T, F: FnMut(Key) -> T>(self, f: F) -> Self::Resolved<T>;
9}
10
11// Sealed marker trait for QueryResults that only return distinct keys.
12pub trait QueryResultDistinct: QueryResult {
13    #[doc(hidden)]
14    fn _seal(_: sealed::Sealed);
15}
16
17mod sealed {
18    pub struct Sealed;
19}
20
21macro_rules! seal {
22    ($($t:ty),*) => {
23        $(
24            impl QueryResultDistinct for $t {
25                fn _seal(_: sealed::Sealed) {}
26            }
27        )*
28    };
29}
30
31// QueryResult for Key itself.
32
33impl QueryResult for Key {
34    type Resolved<T> = T;
35    fn map<T, F: FnMut(Key) -> T>(self, mut f: F) -> Self::Resolved<T> {
36        f(self)
37    }
38}
39seal!(Key);
40
41// QueryResult for simple types that do not depend on keys.
42
43#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
44pub struct Plain<T>(pub T);
45impl<T> QueryResult for Plain<T> {
46    type Resolved<U> = T;
47
48    fn map<U, F: FnMut(Key) -> U>(self, _f: F) -> Self::Resolved<U> {
49        self.0
50    }
51}
52
53macro_rules! impl_query_result_plain {
54    ($($t:ty),*) => {
55        $(
56            impl QueryResult for $t {
57                type Resolved<U> = $t;
58
59                fn map<U, F: FnMut(Key) -> U>(self, _f: F) -> Self::Resolved<U> {
60                    self
61                }
62            }
63        )*
64    };
65}
66
67impl_query_result_plain!(usize, isize);
68impl_query_result_plain!(u8, u16, u32, u64, u128);
69impl_query_result_plain!(i8, i16, i32, i64, i128);
70impl_query_result_plain!(f32, f64);
71impl_query_result_plain!(bool);
72impl_query_result_plain!(char);
73impl_query_result_plain!(String);
74impl_query_result_plain!(&'static str);
75impl_query_result_plain!(
76    std::num::NonZeroU8,
77    std::num::NonZeroU16,
78    std::num::NonZeroU32,
79    std::num::NonZeroU64,
80    std::num::NonZeroU128
81);
82impl_query_result_plain!(
83    std::num::NonZeroI8,
84    std::num::NonZeroI16,
85    std::num::NonZeroI32,
86    std::num::NonZeroI64,
87    std::num::NonZeroI128
88);
89impl_query_result_plain!(std::num::NonZeroUsize);
90impl_query_result_plain!(std::num::NonZeroIsize);
91
92macro_rules! impl_query_result_plain_wrapper {
93    ($t:ident) => {
94        impl<T: QueryResult> QueryResult for $t<T> {
95            type Resolved<U> = $t<T::Resolved<U>>;
96
97            fn map<U, F: FnMut(Key) -> U>(self, f: F) -> Self::Resolved<U> {
98                $t(self.0.map(f))
99            }
100        }
101    };
102}
103
104impl_query_result_plain_wrapper!(Wrapping);
105
106// QueryResult for Array-like types.
107
108impl<T: QueryResult> QueryResult for Option<T> {
109    type Resolved<U> = Option<T::Resolved<U>>;
110
111    fn map<U, F: FnMut(Key) -> U>(self, f: F) -> Self::Resolved<U> {
112        self.map(|v| v.map(f))
113    }
114}
115
116impl<T: QueryResult, E: QueryResult> QueryResult for Result<T, E> {
117    type Resolved<U> = Result<T::Resolved<U>, E::Resolved<U>>;
118
119    fn map<U, F: FnMut(Key) -> U>(self, f: F) -> Self::Resolved<U> {
120        match self {
121            Ok(v) => Ok(v.map(f)),
122            Err(e) => Err(e.map(f)),
123        }
124    }
125}
126
127impl<T: QueryResult> QueryResult for Vec<T> {
128    type Resolved<U> = Vec<T::Resolved<U>>;
129
130    fn map<U, F: FnMut(Key) -> U>(self, mut f: F) -> Self::Resolved<U> {
131        self.into_iter().map(|v| v.map(&mut f)).collect()
132    }
133}
134
135impl<T: QueryResult, const N: usize> QueryResult for [T; N] {
136    type Resolved<U> = [T::Resolved<U>; N];
137
138    fn map<U, F: FnMut(Key) -> U>(self, mut f: F) -> Self::Resolved<U> {
139        self.map(|v| v.map(&mut f))
140    }
141}
142
143// QueryResult (and QueryResultDistinct) for Set-like types.
144impl QueryResult for std::collections::HashSet<Key> {
145    type Resolved<T> = Vec<T>;
146
147    fn map<T, F: FnMut(Key) -> T>(self, f: F) -> Self::Resolved<T> {
148        self.into_iter().map(f).collect()
149    }
150}
151seal!(std::collections::HashSet<Key>);
152
153impl QueryResult for std::collections::BTreeSet<Key> {
154    type Resolved<T> = Vec<T>;
155
156    fn map<T, F: FnMut(Key) -> T>(self, f: F) -> Self::Resolved<T> {
157        self.into_iter().map(f).collect()
158    }
159}
160seal!(std::collections::BTreeSet<Key>);
161
162// UnsafeDistinct wrapper
163
164#[doc(hidden)]
165pub struct UnsafeDistinct<T>(pub T);
166impl<T: QueryResult> QueryResult for UnsafeDistinct<T> {
167    type Resolved<U> = T::Resolved<U>;
168    fn map<U, F: FnMut(Key) -> U>(self, f: F) -> Self::Resolved<U> {
169        self.0.map(f)
170    }
171}
172impl<T: QueryResultDistinct> QueryResultDistinct for UnsafeDistinct<T> {
173    fn _seal(_: sealed::Sealed) {}
174}
175
176// QueryResult for tuples
177
178macro_rules! impl_query_result_tuple {
179    ($($name:ident),+) => {
180        impl<$($name: QueryResult),+> QueryResult for ($($name,)+) {
181            type Resolved<U> = ($($name::Resolved<U>,)+);
182
183            fn map<U, F: FnMut(Key) -> U>(self, mut f: F) -> Self::Resolved<U> {
184                let ($($name,)+) = self;
185                ($($name.map(&mut f),)+)
186            }
187        }
188    };
189}
190
191impl_query_result_tuple!(_1);
192impl_query_result_tuple!(_1, _2);
193impl_query_result_tuple!(_1, _2, _3);
194impl_query_result_tuple!(_1, _2, _3, _4);
195impl_query_result_tuple!(_1, _2, _3, _4, _5);
196impl_query_result_tuple!(_1, _2, _3, _4, _5, _6);
197impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7);
198impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8);
199impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9);
200impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10);
201impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11);
202impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
203impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13);
204impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14);
205impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15);
206impl_query_result_tuple!(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16);