diff options
Diffstat (limited to 'rprt-engine/src/monad.rs')
| -rw-r--r-- | rprt-engine/src/monad.rs | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/rprt-engine/src/monad.rs b/rprt-engine/src/monad.rs index ae0df3e..34ff46b 100644 --- a/rprt-engine/src/monad.rs +++ b/rprt-engine/src/monad.rs @@ -1,6 +1,6 @@ use crate::{ - selection::Selection, - state::{EditorState, EvaluationResult}, + selection::{Selection, SelectionError}, + state::{EditorState, EvaluationResult, GroupedChangeError}, }; pub enum EvaluationStrategy { @@ -8,43 +8,67 @@ pub enum EvaluationStrategy { Grouped, } -pub type MonadicState = (EditorState, EvaluationResult); +#[derive(Debug)] +pub enum EvaluationError { + Selection(SelectionError), + GroupedChange(GroupedChangeError), +} + +impl From<SelectionError> for EvaluationError { + fn from(err: SelectionError) -> Self { + EvaluationError::Selection(err) + } +} + +impl From<GroupedChangeError> for EvaluationError { + fn from(err: GroupedChangeError) -> Self { + EvaluationError::GroupedChange(err) + } +} pub struct EditorStateMonad { - func: Box<dyn Fn(EditorState) -> MonadicState>, + func: Box<dyn Fn(&EditorState) -> EvaluationResult>, } impl EditorStateMonad { - pub fn new(f: impl Fn(EditorState) -> MonadicState + 'static) -> Self { + pub fn new(f: impl Fn(&EditorState) -> EvaluationResult + 'static) -> Self { Self { func: Box::new(f) } } - pub fn run(&self, initial_state: EditorState) -> MonadicState { - (self.func)(initial_state) + pub fn run(&self, state: &EditorState) -> EvaluationResult { + (self.func)(state) } - pub fn run_with_strategy<E>( + pub fn run_with_strategy( monads: Vec<EditorStateMonad>, strategy: EvaluationStrategy, - initial_state: EditorState, - ) -> Result<MonadicState, E> { + state: &mut EditorState, + ) -> Result<Selection, EvaluationError> { match strategy { EvaluationStrategy::Sequential => { - let mut state_changes = Vec::new(); let mut last_selection = Selection::empty(); - let mut current_state = initial_state; for monad in monads { - let (new_state, (sel, st_ch)) = monad.run(current_state); - current_state = new_state; + let (sel, state_changes) = monad.run(state); + state.commit_changes(state_changes); last_selection = sel; - state_changes.extend(st_ch); } - Ok((current_state, (last_selection, state_changes))) + Ok(last_selection) } EvaluationStrategy::Grouped => { - panic!("TODO") + let mut arms = Vec::new(); + let mut all_selections = Vec::new(); + + for monad in monads { + let (sel, state_changes) = monad.run(state); + all_selections.push(sel); + arms.push(state_changes); + } + + state.commit_changes_grouped(arms)?; + + Ok(Selection::union(all_selections)?) } } } |
