bonsaidb_core/schema/view/
map.rs

1use std::collections::BTreeMap;
2use std::fmt::Debug;
3
4use arc_bytes::serde::Bytes;
5use serde::{Deserialize, Serialize};
6
7use crate::document::{CollectionHeader, DocumentId, Header, OwnedDocument};
8use crate::schema::view::{self, ByteSource, Key, SerializedView, View, ViewSchema};
9use crate::schema::Collection;
10
11/// A document's entry in a View's mappings.
12#[derive(Eq, PartialEq, Debug)]
13pub struct Map<K = (), V = ()> {
14    /// The header of the document that emitted this entry.
15    pub source: Header,
16
17    /// The key used to index the View.
18    pub key: K,
19
20    /// An associated value stored in the view.
21    pub value: V,
22}
23
24impl<K, V> Map<K, V> {
25    /// Serializes this map.
26    pub(crate) fn serialized<'a, View>(&self) -> Result<Serialized, view::Error>
27    where
28        K: Key<'a>,
29        View: SerializedView<Value = V>,
30    {
31        Ok(Serialized {
32            source: self.source.clone(),
33            key: Bytes::from(
34                self.key
35                    .as_ord_bytes()
36                    .map_err(view::Error::key_serialization)?
37                    .to_vec(),
38            ),
39            value: Bytes::from(View::serialize(&self.value)?),
40        })
41    }
42}
43
44impl<K, V> Map<K, V> {
45    /// Creates a new Map entry for the document with id `source`.
46    pub const fn new(source: Header, key: K, value: V) -> Self {
47        Self { source, key, value }
48    }
49}
50
51/// A document's entry in a View's mappings.
52#[derive(Eq, PartialEq, Debug)]
53pub struct CollectionMap<PrimaryKey, K = (), V = ()> {
54    /// The header of the document that emitted this entry.
55    pub source: CollectionHeader<PrimaryKey>,
56
57    /// The key used to index the View.
58    pub key: K,
59
60    /// An associated value stored in the view.
61    pub value: V,
62}
63
64/// This type is the result of `query()`. It is a list of mappings, which
65/// contains:
66///
67/// - The key emitted during the map function.
68/// - The value emitted during the map function.
69/// - The source document header that the mappings originated from.
70pub type ViewMappings<V> = Vec<
71    CollectionMap<
72        <<V as View>::Collection as Collection>::PrimaryKey,
73        <V as View>::Key,
74        <V as View>::Value,
75    >,
76>;
77
78/// A collection of [`Map`]s.
79#[derive(Debug, Eq, PartialEq)]
80#[must_use]
81pub enum Mappings<K = (), V = ()> {
82    /// Zero or one mappings.
83    Simple(Option<Map<K, V>>),
84    /// More than one mapping.
85    List(Vec<Map<K, V>>),
86}
87
88impl<K, V> Default for Mappings<K, V> {
89    fn default() -> Self {
90        Self::none()
91    }
92}
93
94impl<K, V> Mappings<K, V> {
95    /// Returns an empty collection of mappings.
96    pub const fn none() -> Self {
97        Self::Simple(None)
98    }
99
100    /// Appends `mapping` to the end of this collection.
101    pub fn push(&mut self, mapping: Map<K, V>) {
102        match self {
103            Self::Simple(existing_mapping) => {
104                *self = if let Some(existing_mapping) = existing_mapping.take() {
105                    Self::List(vec![existing_mapping, mapping])
106                } else {
107                    Self::Simple(Some(mapping))
108                };
109            }
110            Self::List(vec) => vec.push(mapping),
111        }
112    }
113
114    /// Appends `mappings` to the end of this collection and returns self.
115    pub fn and(mut self, mappings: Self) -> Self {
116        self.extend(mappings);
117        self
118    }
119
120    /// Returns an iterator for these mappings.
121    pub fn iter(&self) -> MappingsIter<'_, K, V> {
122        self.into_iter()
123    }
124
125    /// Returns the number of mappings contained.
126    pub fn len(&self) -> usize {
127        match self {
128            Mappings::Simple(None) => 0,
129            Mappings::Simple(Some(_)) => 1,
130            Mappings::List(v) => v.len(),
131        }
132    }
133
134    /// Returns true if there are no mappings in this collection.
135    pub fn is_empty(&self) -> bool {
136        self.len() == 0
137    }
138}
139
140impl<K, V> Extend<Map<K, V>> for Mappings<K, V> {
141    fn extend<T: IntoIterator<Item = Map<K, V>>>(&mut self, iter: T) {
142        let iter = iter.into_iter();
143        for map in iter {
144            self.push(map);
145        }
146    }
147}
148
149impl<K, V> FromIterator<Map<K, V>> for Mappings<K, V> {
150    fn from_iter<T: IntoIterator<Item = Map<K, V>>>(iter: T) -> Self {
151        let mut mappings = Self::none();
152        mappings.extend(iter);
153        mappings
154    }
155}
156
157impl<K, V> FromIterator<Self> for Mappings<K, V> {
158    fn from_iter<T: IntoIterator<Item = Self>>(iter: T) -> Self {
159        let mut iter = iter.into_iter();
160        if let Some(mut collected) = iter.next() {
161            for mappings in iter {
162                collected.extend(mappings);
163            }
164            collected
165        } else {
166            Self::none()
167        }
168    }
169}
170
171impl<K, V> IntoIterator for Mappings<K, V> {
172    type IntoIter = MappingsIntoIter<K, V>;
173    type Item = Map<K, V>;
174
175    fn into_iter(self) -> Self::IntoIter {
176        match self {
177            Mappings::Simple(option) => MappingsIntoIter::Inline(option),
178            Mappings::List(list) => MappingsIntoIter::Vec(list.into_iter()),
179        }
180    }
181}
182
183impl<'a, K, V> IntoIterator for &'a Mappings<K, V> {
184    type IntoIter = MappingsIter<'a, K, V>;
185    type Item = &'a Map<K, V>;
186
187    fn into_iter(self) -> Self::IntoIter {
188        match self {
189            Mappings::Simple(option) => MappingsIter::Inline(option.iter()),
190            Mappings::List(list) => MappingsIter::Vec(list.iter()),
191        }
192    }
193}
194
195/// An iterator over [`Mappings`] that returns owned [`Map`] entries.
196pub enum MappingsIntoIter<K = (), V = ()> {
197    /// An iterator over a [`Mappings::Simple`] value.
198    Inline(Option<Map<K, V>>),
199    /// An iterator over a [`Mappings::List`] value.
200    Vec(std::vec::IntoIter<Map<K, V>>),
201}
202
203impl<K, V> Iterator for MappingsIntoIter<K, V> {
204    type Item = Map<K, V>;
205
206    fn next(&mut self) -> Option<Self::Item> {
207        match self {
208            MappingsIntoIter::Inline(opt) => opt.take(),
209            MappingsIntoIter::Vec(iter) => iter.next(),
210        }
211    }
212}
213
214/// An iterator over [`Mappings`] that returns [`Map`] entry references.
215pub enum MappingsIter<'a, K = (), V = ()> {
216    /// An iterator over a [`Mappings::Simple`] value.
217    Inline(std::option::Iter<'a, Map<K, V>>),
218    /// An iterator over a [`Mappings::List`] value.
219    Vec(std::slice::Iter<'a, Map<K, V>>),
220}
221
222impl<'a, K, V> Iterator for MappingsIter<'a, K, V> {
223    type Item = &'a Map<K, V>;
224
225    fn next(&mut self) -> Option<Self::Item> {
226        match self {
227            MappingsIter::Inline(i) => i.next(),
228            MappingsIter::Vec(i) => i.next(),
229        }
230    }
231}
232
233/// A collection of mappings and the associated documents.
234pub struct MappedDocuments<D, V: View> {
235    /// The collection of mappings.
236    pub mappings: ViewMappings<V>,
237    /// All associated documents by ID.
238    ///
239    /// Documents can appear in a mapping query multiple times. As a result, they are stored separately to avoid duplication.
240    pub documents: BTreeMap<<V::Collection as Collection>::PrimaryKey, D>,
241}
242
243impl<D, V: View> MappedDocuments<D, V> {
244    /// The number of mappings contained in this collection.
245    #[must_use]
246    pub fn len(&self) -> usize {
247        self.mappings.len()
248    }
249
250    /// Returns true if there are no mappings in this collection.
251    #[must_use]
252    pub fn is_empty(&self) -> bool {
253        self.len() == 0
254    }
255
256    /// Returns the mapped document at`index`, or `None` if `index >=
257    /// self.len()`.
258    #[must_use]
259    #[allow(clippy::missing_panics_doc)]
260    pub fn get(&self, index: usize) -> Option<MappedDocument<'_, D, V::Key, V::Value>> {
261        if index < self.len() {
262            let mapping = &self.mappings[index];
263            let document = self
264                .documents
265                .get(&mapping.source.id)
266                .expect("missing mapped document");
267            Some(MappedDocument {
268                key: &mapping.key,
269                value: &mapping.value,
270                document,
271            })
272        } else {
273            None
274        }
275    }
276}
277
278impl<D, V: View> Debug for MappedDocuments<D, V>
279where
280    V::Key: Debug,
281    V::Value: Debug,
282    D: Debug,
283    <V::Collection as Collection>::PrimaryKey: Debug,
284{
285    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286        f.debug_struct("MappedDocuments")
287            .field("mappings", &self.mappings)
288            .field("documents", &self.documents)
289            .finish()
290    }
291}
292
293/// An iterator of mapped documents.
294pub struct MappedDocumentsIter<'a, D, V: View> {
295    docs: &'a MappedDocuments<D, V>,
296    index: usize,
297}
298
299impl<'a, D, V: View> IntoIterator for &'a MappedDocuments<D, V> {
300    type IntoIter = MappedDocumentsIter<'a, D, V>;
301    type Item = MappedDocument<'a, D, V::Key, V::Value>;
302
303    fn into_iter(self) -> Self::IntoIter {
304        MappedDocumentsIter {
305            docs: self,
306            index: 0,
307        }
308    }
309}
310
311impl<'a, D, V: View> Iterator for MappedDocumentsIter<'a, D, V> {
312    type Item = MappedDocument<'a, D, V::Key, V::Value>;
313
314    fn next(&mut self) -> Option<Self::Item> {
315        let doc = self.docs.get(self.index);
316        self.index = self.index.saturating_add(1);
317        doc
318    }
319}
320
321/// A mapped document returned from a view query.
322pub struct MappedDocument<'a, D, K, V> {
323    /// The key that this document mapped to.
324    pub key: &'a K,
325    /// The associated value of this key.
326    pub value: &'a V,
327    /// The source document of this mapping.
328    pub document: &'a D,
329}
330
331/// Represents a document's entry in a View's mappings, serialized and ready to store.
332#[derive(Serialize, Deserialize, Debug, Clone)]
333pub struct Serialized {
334    /// The header of the document that emitted this entry.
335    pub source: Header,
336
337    /// The key used to index the View.Operation
338    pub key: Bytes,
339
340    /// An associated value stored in the view.Operation
341    pub value: Bytes,
342}
343
344impl Serialized {
345    /// Deserializes this map.
346    pub fn deserialized<View: SerializedView>(
347        &self,
348    ) -> Result<Map<View::Key, View::Value>, view::Error> {
349        Ok(Map::new(
350            self.source.clone(),
351            <View::Key as Key>::from_ord_bytes(ByteSource::Borrowed(&self.key))
352                .map_err(view::Error::key_serialization)?,
353            View::deserialize(&self.value)?,
354        ))
355    }
356}
357
358/// A serialized [`MappedDocument`](MappedDocument).
359#[derive(Clone, Serialize, Deserialize, Debug)]
360pub struct MappedSerializedDocuments {
361    /// The serialized mapped value.
362    pub mappings: Vec<Serialized>,
363    /// The source document.
364    pub documents: BTreeMap<DocumentId, OwnedDocument>,
365}
366
367impl MappedSerializedDocuments {
368    /// Deserialize into a [`MappedDocument`](MappedDocument).
369    pub fn deserialized<View: SerializedView>(
370        self,
371    ) -> Result<MappedDocuments<OwnedDocument, View>, crate::Error> {
372        let mappings = self
373            .mappings
374            .iter()
375            .map(|mapping| {
376                let deserialized = Serialized::deserialized::<View>(mapping)?;
377                Ok(CollectionMap {
378                    source: deserialized.source.try_into()?,
379                    key: deserialized.key,
380                    value: deserialized.value,
381                })
382            })
383            .collect::<Result<Vec<_>, crate::Error>>()?;
384
385        Ok(MappedDocuments {
386            mappings,
387            documents: self
388                .documents
389                .into_iter()
390                .map(|(key, value)| {
391                    let key = key.deserialize()?;
392                    Ok((key, value))
393                })
394                .collect::<Result<BTreeMap<_, _>, crate::Error>>()?,
395        })
396    }
397}
398
399/// A key value pair
400#[derive(Clone, Eq, PartialEq, Debug)]
401pub struct MappedValue<K, V> {
402    /// The key responsible for generating the value
403    pub key: K,
404
405    /// The value generated by the `View`
406    pub value: V,
407}
408
409impl<K, V> MappedValue<K, V> {
410    /// Returns a new instance with the key/value pair.
411    pub const fn new(key: K, value: V) -> Self {
412        Self { key, value }
413    }
414}
415
416/// A mapped value in a [`View`].
417pub type ViewMappedValue<'doc, V> =
418    MappedValue<<V as ViewSchema>::MappedKey<'doc>, <<V as ViewSchema>::View as View>::Value>;
419
420/// A serialized [`MappedValue`].
421#[derive(Clone, Serialize, Deserialize, Debug)]
422pub struct MappedSerializedValue {
423    /// The serialized key.
424    pub key: Bytes,
425    /// The serialized value.
426    pub value: Bytes,
427}