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    type Item;
15    type Iter: IntoIterator<Item = Self::Item>;
16    fn spread(self) -> (Self::Iter, TribleSet);
17}
18
19impl<I: IntoIterator> Spread for I {
20    type Item = I::Item;
21    type Iter = I;
22    fn spread(self) -> (Self::Iter, TribleSet) {
23        (self, TribleSet::new())
24    }
25}
26
27impl Spread for Fragment {
28    type Item = Id;
29    type Iter = std::vec::IntoIter<Id>;
30    fn spread(self) -> (Self::Iter, TribleSet) {
31        let (exports, facts) = self.into_parts();
32        let ids: Vec<Id> = exports
33            .iter_ordered()
34            .map(|raw| Id::new(*raw).expect("export ids are non-nil"))
35            .collect();
36        (ids.into_iter(), facts)
37    }
38}