diff options
| author | tslil <tslil@posteo.de> | 2026-03-21 17:56:08 +0000 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-03-21 20:09:34 +0000 |
| commit | 89d299376c97a3f866dccc15321713ce955d8125 (patch) | |
| tree | 122bde2e89120bbe21f594e4209f47c9fc0fa352 /rprt-engine/src/evaluate.rs | |
| parent | fb0d0b91bfd45d1911e993ca753d81da5e60f60c (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.rs | 72 |
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)) } } } |
