aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine/src/monad.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rprt-engine/src/monad.rs')
-rw-r--r--rprt-engine/src/monad.rs58
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)?)
}
}
}