use std::ops::{Add, AddAssign, Deref};
use crate::id::Id;
use crate::id::RawId;
use crate::patch::Entry;
use crate::patch::PATCH;
use super::Trible;
use super::TribleSet;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Fragment {
exports: PATCH<16>,
facts: TribleSet,
}
impl Fragment {
pub fn empty() -> Self {
Self::default()
}
pub fn rooted(root: Id, facts: TribleSet) -> Self {
let mut exports = PATCH::<16>::new();
let raw: RawId = root.into();
exports.insert(&Entry::new(&raw));
Self { exports, facts }
}
pub fn new<I>(exports: I, facts: TribleSet) -> Self
where
I: IntoIterator<Item = Id>,
{
let mut export_set = PATCH::<16>::new();
for id in exports {
let raw: RawId = id.into();
export_set.insert(&Entry::new(&raw));
}
Self {
exports: export_set,
facts,
}
}
pub fn exports(&self) -> impl Iterator<Item = Id> + '_ {
self.exports
.iter_ordered()
.map(|raw| Id::new(*raw).expect("export ids are non-nil"))
}
pub fn root(&self) -> Option<Id> {
if self.exports.len() == 1 {
let raw = self
.exports
.iter_ordered()
.next()
.expect("len() == 1 implies a first element exists");
Some(Id::new(*raw).expect("export ids are non-nil"))
} else {
None
}
}
pub fn facts(&self) -> &TribleSet {
&self.facts
}
pub fn into_facts(self) -> TribleSet {
self.facts
}
pub fn into_parts(self) -> (PATCH<16>, TribleSet) {
(self.exports, self.facts)
}
}
impl Deref for Fragment {
type Target = TribleSet;
fn deref(&self) -> &Self::Target {
&self.facts
}
}
impl<'a> IntoIterator for &'a Fragment {
type Item = &'a Trible;
type IntoIter = super::tribleset::TribleSetIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.facts.iter()
}
}
impl AddAssign for Fragment {
fn add_assign(&mut self, rhs: Self) {
self.facts += rhs.facts;
self.exports.union(rhs.exports);
}
}
impl AddAssign<TribleSet> for Fragment {
fn add_assign(&mut self, rhs: TribleSet) {
self.facts += rhs;
}
}
impl Add for Fragment {
type Output = Self;
fn add(mut self, rhs: Self) -> Self::Output {
self += rhs;
self
}
}
impl Add<TribleSet> for Fragment {
type Output = Self;
fn add(mut self, rhs: TribleSet) -> Self::Output {
self += rhs;
self
}
}
impl AddAssign<Fragment> for TribleSet {
fn add_assign(&mut self, rhs: Fragment) {
self.union(rhs.facts);
}
}
impl Add<Fragment> for TribleSet {
type Output = Self;
fn add(mut self, rhs: Fragment) -> Self::Output {
self += rhs;
self
}
}
impl From<Fragment> for TribleSet {
fn from(value: Fragment) -> Self {
value.facts
}
}