Skip to main content

triblespace_core/trible/
spread.rs

1use crate::id::Id;
2use crate::id::RawId;
3use crate::patch::{IdentitySchema, PATCHIntoOrderedIterator};
4
5use super::Fragment;
6
7/// Trait for types that can be "spread" into an `entity!` repeated attribute.
8///
9/// A spread produces an iterator of attribute values, plus a Fragment
10/// of extras (facts + blobs) that gets merged into the entity's result
11/// fragment.
12///
13/// Plain iterators return an empty extras Fragment. A [`Fragment`] returns
14/// its exported ids as the values and its contained facts + blobs as the
15/// extras.
16pub trait Spread {
17    /// The type of each yielded value.
18    type Item;
19    /// The iterator type returned by [`spread`](Spread::spread).
20    type Iter: IntoIterator<Item = Self::Item>;
21    /// Decomposes the value into an iterator of items and extras (facts +
22    /// blobs) to merge.
23    fn spread(self) -> (Self::Iter, Fragment);
24}
25
26impl<I: IntoIterator> Spread for I {
27    type Item = I::Item;
28    type Iter = I;
29    fn spread(self) -> (Self::Iter, Fragment) {
30        (self, Fragment::empty())
31    }
32}
33
34/// Free function (not a closure) so `Map`'s type is nameable in
35/// `Spread::Iter` below — keeps `Fragment::spread` allocation-free.
36fn raw_to_id(raw: RawId) -> Id {
37    Id::new(raw).expect("export ids are non-nil")
38}
39
40impl Spread for Fragment {
41    type Item = Id;
42    type Iter = std::iter::Map<
43        PATCHIntoOrderedIterator<16, IdentitySchema, ()>,
44        fn(RawId) -> Id,
45    >;
46    fn spread(self) -> (Self::Iter, Fragment) {
47        let (exports, facts, blobs) = self.into_parts();
48        // Wrap the remaining facts + blobs as an extras fragment with
49        // no exports — the exports are consumed lazily as the spread
50        // values via the mapping iterator below.
51        let extras = Fragment::from_facts_and_blobs(facts, blobs);
52        let iter = exports.into_iter_ordered().map(raw_to_id as fn(_) -> _);
53        (iter, extras)
54    }
55}