aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine/src/evaluate.rs
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2026-03-21 17:56:08 +0000
committertslil <tslil@posteo.de>2026-03-21 20:09:34 +0000
commit89d299376c97a3f866dccc15321713ce955d8125 (patch)
tree122bde2e89120bbe21f594e4209f47c9fc0fa352 /rprt-engine/src/evaluate.rs
parentfb0d0b91bfd45d1911e993ca753d81da5e60f60c (diff)
think the commit logic is worked out now for eager commits
Diffstat (limited to 'rprt-engine/src/evaluate.rs')
-rw-r--r--rprt-engine/src/evaluate.rs72
1 files changed, 52 insertions, 20 deletions
diff --git a/rprt-engine/src/evaluate.rs b/rprt-engine/src/evaluate.rs
index b23c1be..a139aa3 100644
--- a/rprt-engine/src/evaluate.rs
+++ b/rprt-engine/src/evaluate.rs
@@ -1,8 +1,8 @@
use crate::{
expression::Composite,
- selection::{Selection, VectoriseError},
+ selection::{Selection, SelectionError, VectoriseError},
selection_functions::{evaluate_selection_function, SFError},
- state::{EditorState, StateResult},
+ state::{EditorState, GroupedChangeError, StateChange, StateResult},
};
use thiserror::Error;
@@ -11,17 +11,35 @@ use thiserror::Error;
pub enum EvaluationError {
#[error("{0}")]
SelectionFunctionError(VectoriseError<SFError>),
+ #[error("{0}")]
+ SelectionUnionError(SelectionError),
+ #[error("Error in processing group {0}")]
+ GroupError(GroupedChangeError),
#[error("Invalid right-only application")]
IROApplication,
#[error("Not yet implemented {0}")]
UnimplementedError(&'static str),
}
+fn commit_if_needed(
+ es: &mut EditorState,
+ changes: Vec<StateChange>,
+ commit: bool,
+) -> Vec<StateChange> {
+ if commit {
+ es.commit_changes(changes);
+ Vec::new()
+ } else {
+ changes
+ }
+}
+
pub fn evaluate(
- es: &EditorState,
+ es: &mut EditorState,
comp: Composite,
left: Option<Selection>,
right: Option<Selection>,
+ commit: bool,
) -> Result<StateResult, EvaluationError> {
if left.is_none() && right.is_some() {
return Err(EvaluationError::IROApplication);
@@ -43,28 +61,42 @@ pub fn evaluate(
}
Composite::Hook { kind, left, right } => Err(EvaluationError::UnimplementedError("hook")),
Composite::Train2 { f, g } => {
- let (left, mut state) = evaluate(es, *f, left, right)?;
- let (sel, more_state) = evaluate(es, *g, Some(left), None)?;
- state.extend(more_state);
- Ok((sel, state))
+ let (left, mut f_changes) = evaluate(es, *f, left, right, commit)?;
+ f_changes = commit_if_needed(es, f_changes, commit);
+ let (sel, g_changes) = evaluate(es, *g, Some(left), None, commit)?;
+ let more_changes = commit_if_needed(es, g_changes, commit);
+ f_changes.extend(more_changes);
+ Ok((sel, f_changes))
}
Composite::Train3 { f, g, h } => {
- let (f_left, mut f_state) = evaluate(es, *f, left.clone(), right.clone())?;
- let (g_right, h_state) = evaluate(es, *h, left, right)?;
- let (sel, g_state) = evaluate(es, *g, Some(f_left), Some(g_right))?;
- f_state.extend(h_state);
- f_state.extend(g_state);
- Ok((sel, f_state))
+ let (f_left, mut f_changes) = evaluate(es, *f, left.clone(), right.clone(), commit)?;
+ f_changes = commit_if_needed(es, f_changes, commit);
+ let (g_right, h_changes) = evaluate(es, *h, left, right, commit)?;
+ let h_changes = commit_if_needed(es, h_changes, commit);
+ let (sel, g_changes) = evaluate(es, *g, Some(f_left), Some(g_right), commit)?;
+ let g_changes = commit_if_needed(es, g_changes, commit);
+ f_changes.extend(h_changes);
+ f_changes.extend(g_changes);
+ Ok((sel, f_changes))
}
Composite::Group { operations } => {
- // TODO: does rust have some monadic failure map thing on first failure?
- let mut selections = Vec::new();
- let mut states = Vec::new();
- for f in operations {
- let (sel, state) = evaluate(es, f, left.clone(), right.clone())?;
- selections.extend(sel);
- states.extend(state);
+ let results: Vec<(Selection, Vec<StateChange>)> = operations
+ .into_iter()
+ .map(|op| evaluate(es, op, left.clone(), right.clone(), commit))
+ .collect::<Result<_, _>>()?;
+
+ let (selections, arms) = results.into_iter().unzip();
+
+ let states = if commit {
+ es.commit_changes_grouped(arms).map(|_| Vec::new())
+ } else {
+ es.validate_grouped_changes(&arms)
+ .map(|_| arms.into_iter().flatten().collect())
}
+ .map_err(EvaluationError::GroupError)?;
+
+ let sel = Selection::union(selections).map_err(EvaluationError::SelectionUnionError)?;
+ Ok((sel, states))
}
}
}