use crate::graph::hash::hash_delta;
use crate::graph::DeterministicGraph;
use crate::GraphError;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RdfDelta {
pub additions: Vec<String>,
pub deletions: Vec<String>,
}
impl RdfDelta {
pub fn new(additions: Vec<String>, deletions: Vec<String>) -> Self {
Self {
additions,
deletions,
}
}
pub fn compute(
baseline: &DeterministicGraph, target: &DeterministicGraph,
) -> Result<Self, GraphError> {
let baseline_quads = baseline.all_quads()?;
let target_quads = target.all_quads()?;
let mut additions = Vec::new();
let mut deletions = Vec::new();
let baseline_set: std::collections::HashSet<String> =
baseline_quads.iter().map(ToString::to_string).collect();
let target_set: std::collections::HashSet<String> =
target_quads.iter().map(ToString::to_string).collect();
for q_str in &target_set {
if !baseline_set.contains(q_str) {
additions.push(q_str.clone());
}
}
for q_str in &baseline_set {
if !target_set.contains(q_str) {
deletions.push(q_str.clone());
}
}
additions.sort();
deletions.sort();
Ok(Self {
additions,
deletions,
})
}
pub fn apply(&self, graph: &DeterministicGraph) -> Result<(), GraphError> {
for del in &self.deletions {
let quad = DeterministicGraph::parse_nquad(del)?;
graph.remove_quad(&quad)?;
}
for add in &self.additions {
let quad = DeterministicGraph::parse_nquad(add)?;
graph.insert_quad(&quad)?;
}
Ok(())
}
pub fn diff(&self, other: &Self) -> Self {
let mut additions = Vec::new();
let self_adds: std::collections::HashSet<_> = self.additions.iter().collect();
for add in &other.additions {
if !self_adds.contains(add) {
additions.push(add.clone());
}
}
let mut deletions = Vec::new();
let self_dels: std::collections::HashSet<_> = self.deletions.iter().collect();
for del in &other.deletions {
if !self_dels.contains(del) {
deletions.push(del.clone());
}
}
Self {
additions,
deletions,
}
}
pub fn hash(&self) -> [u8; 32] {
hash_delta(&self.additions, &self.deletions)
}
}