Files
ARCADIA-Studio/crates/oa-desktop/src/semantic_review/history.rs
T

96 lines
3.1 KiB
Rust

use super::*;
pub(super) fn resettable(_facet: &FacetSelector) -> bool {
true
}
impl ReviewRow {
pub(super) fn effective_trace(&self, project: &Project) -> Option<Trace> {
let mut trace = project.traces.get(&self.trace?)?.clone();
if let Some(baseline) = trace.baseline.as_mut().and_then(|b| b.semantic.as_mut()) {
baseline
.facets
.retain(|f| !self.resets.contains(&f.selector()));
}
Some(trace)
}
pub(super) fn reset_history(
&mut self,
project: &Project,
facet: FacetSelector,
reset: bool,
) -> Result<(), String> {
if !reset && self.resets.remove(&facet) {
return Ok(());
}
let exists = self
.trace
.and_then(|id| project.traces.get(&id))
.and_then(|t| t.baseline.as_ref())
.and_then(|b| b.semantic.as_ref())
.is_some_and(|b| b.facets.iter().any(|f| f.selector() == facet));
if !exists || !resettable(&facet) {
return Err("Choose an exact existing observation to reset.".into());
}
if reset {
self.resets.insert(facet);
} else {
self.resets.remove(&facet);
}
Ok(())
}
}
// Only persisted typed addresses establish correspondence. Order vectors and
// arbitrary scalar values cannot be zipped or searched for UUID-shaped prose.
pub(super) fn reviewed_pairs(
row: &ReviewRow,
project: &Project,
) -> Result<BTreeMap<Id, Id>, String> {
let trace = row
.effective_trace(project)
.ok_or("Choose an existing trace history.")?;
let mut result = BTreeMap::new();
for fact in trace
.baseline
.iter()
.flat_map(|b| b.semantic.iter())
.flat_map(|b| &b.facets)
{
let mut pairs = vec![];
match fact.selector() {
FacetSelector::Member { keys, .. }
| FacetSelector::Binding(keys)
| FacetSelector::Child(keys)
| FacetSelector::Incident { keys, .. }
| FacetSelector::Artifact { keys, .. } => {
if let (Some(oa), Some(sa)) = (keys.oa, keys.sa) {
pairs.push((oa, sa));
}
}
FacetSelector::Annotation(KeyPair {
oa: Some(oa),
sa: Some(sa),
}) => {
if oa.path.len() != sa.path.len() {
return Err("Historical annotation addresses have different depths; restore their correspondence explicitly.".into());
}
pairs.extend(
oa.path
.into_iter()
.chain([oa.field])
.zip(sa.path.into_iter().chain([sa.field])),
);
}
_ => {}
}
for (oa, sa) in pairs {
if result.insert(oa, sa).is_some_and(|old| old != sa) {
return Err("Historical observations pair one Operational identity with different System identities. Resolve exact history before restoring pairs.".into());
}
}
}
Ok(result)
}