composable_indexes/core/
query_result.rs

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