Skip to main content

triblespace_core/trible/
spread.rs

1use crate::id::Id;
2
3use super::Fragment;
4use super::TribleSet;
5
6/// Trait for types that can be "spread" into an `entity!` repeated attribute.
7///
8/// A spread produces an iterator of attribute values, plus an optional
9/// set of extra facts that are merged into the entity's result fragment.
10///
11/// Plain iterators return an empty extra-facts set. A [`Fragment`] returns
12/// its exported ids as the values and its contained facts as the extras.
13pub trait Spread {
14    /// The type of each yielded value.
15    type Item;
16    /// The iterator type returned by [`spread`](Spread::spread).
17    type Iter: IntoIterator<Item = Self::Item>;
18    /// Decomposes the value into an iterator of items and extra facts to merge.
19    fn spread(self) -> (Self::Iter, TribleSet);
20}
21
22impl<I: IntoIterator> Spread for I {
23    type Item = I::Item;
24    type Iter = I;
25    fn spread(self) -> (Self::Iter, TribleSet) {
26        (self, TribleSet::new())
27    }
28}
29
30impl Spread for Fragment {
31    type Item = Id;
32    type Iter = std::vec::IntoIter<Id>;
33    fn spread(self) -> (Self::Iter, TribleSet) {
34        let (exports, facts) = self.into_parts();
35        let ids: Vec<Id> = exports
36            .iter_ordered()
37            .map(|raw| Id::new(*raw).expect("export ids are non-nil"))
38            .collect();
39        (ids.into_iter(), facts)
40    }
41}