aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine
diff options
context:
space:
mode:
Diffstat (limited to 'rprt-engine')
-rw-r--r--rprt-engine/src/lib.rs1
-rw-r--r--rprt-engine/src/monad.rs51
2 files changed, 52 insertions, 0 deletions
diff --git a/rprt-engine/src/lib.rs b/rprt-engine/src/lib.rs
index 3ef4ac1..0ae9d2d 100644
--- a/rprt-engine/src/lib.rs
+++ b/rprt-engine/src/lib.rs
@@ -2,6 +2,7 @@
pub mod buffer;
pub mod expression;
+pub mod monad;
pub mod parser;
pub mod selection;
pub mod state;
diff --git a/rprt-engine/src/monad.rs b/rprt-engine/src/monad.rs
new file mode 100644
index 0000000..ae0df3e
--- /dev/null
+++ b/rprt-engine/src/monad.rs
@@ -0,0 +1,51 @@
+use crate::{
+ selection::Selection,
+ state::{EditorState, EvaluationResult},
+};
+
+pub enum EvaluationStrategy {
+ Sequential,
+ Grouped,
+}
+
+pub type MonadicState = (EditorState, EvaluationResult);
+
+pub struct EditorStateMonad {
+ func: Box<dyn Fn(EditorState) -> MonadicState>,
+}
+
+impl EditorStateMonad {
+ pub fn new(f: impl Fn(EditorState) -> MonadicState + 'static) -> Self {
+ Self { func: Box::new(f) }
+ }
+
+ pub fn run(&self, initial_state: EditorState) -> MonadicState {
+ (self.func)(initial_state)
+ }
+
+ pub fn run_with_strategy<E>(
+ monads: Vec<EditorStateMonad>,
+ strategy: EvaluationStrategy,
+ initial_state: EditorState,
+ ) -> Result<MonadicState, E> {
+ 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;
+ last_selection = sel;
+ state_changes.extend(st_ch);
+ }
+
+ Ok((current_state, (last_selection, state_changes)))
+ }
+ EvaluationStrategy::Grouped => {
+ panic!("TODO")
+ }
+ }
+ }
+}