aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine
diff options
context:
space:
mode:
authortslil <tslil@posteo.de>2025-10-28 20:14:27 +0000
committertslil <tslil@posteo.de>2025-10-28 21:49:26 +0000
commit2832ffbe077230b89222479da8b737142c9efe1b (patch)
tree2117fcd989859619fdbf59a59d72a67621c43667 /rprt-engine
parent7c36fb82df24cfa96ad2d2bf3fa769142c178fc1 (diff)
Playing with macro_rules, sigh.
Diffstat (limited to 'rprt-engine')
-rw-r--r--rprt-engine/src/selection.rs17
-rw-r--r--rprt-engine/src/selection_function.rs384
2 files changed, 189 insertions, 212 deletions
diff --git a/rprt-engine/src/selection.rs b/rprt-engine/src/selection.rs
index 9e619a4..341c6ad 100644
--- a/rprt-engine/src/selection.rs
+++ b/rprt-engine/src/selection.rs
@@ -83,6 +83,15 @@ where
SelectionError(SelectionError),
}
+impl<E> From<E> for VectoriseError<E>
+where
+ E: std::error::Error + 'static,
+{
+ fn from(err: E) -> Self {
+ VectoriseError::ProcessingError(err)
+ }
+}
+
impl Selection {
pub fn empty() -> Self {
Self::MultiRanges {
@@ -273,10 +282,10 @@ impl Selection {
}
pub fn vectorise<S, E>(
- fn_rank_zero: impl Fn(&S, BufferID, usize) -> Result<Selection, E>,
- fn_rank_one: impl Fn(&S, BufferID, &Interval) -> Result<Selection, E>,
+ &self,
state: &S,
- selection: &Selection,
+ fn_rank_zero: impl Fn(&S, BufferID, usize) -> Result<Selection, E> + 'static,
+ fn_rank_one: impl Fn(&S, BufferID, &Interval) -> Result<Selection, E> + 'static,
) -> Result<Selection, VectoriseError<E>>
where
E: std::error::Error + 'static,
@@ -289,7 +298,7 @@ impl Selection {
.collect::<Result<_, _>>()
};
- match selection {
+ match self {
&Self::Position { buffer_id, pos } => {
fn_rank_zero(state, buffer_id, pos).map_err(ProcessingError)
}
diff --git a/rprt-engine/src/selection_function.rs b/rprt-engine/src/selection_function.rs
index 67f6ccc..ac3d221 100644
--- a/rprt-engine/src/selection_function.rs
+++ b/rprt-engine/src/selection_function.rs
@@ -1,5 +1,5 @@
use crate::buffer::BufferID;
-use crate::selection::{Interval, Selection, VectoriseError};
+use crate::selection::{Selection, VectoriseError};
use crate::state::EditorState;
use thiserror::Error;
@@ -7,232 +7,200 @@ use thiserror::Error;
pub enum SFError {
#[error("Could not find buffer {0}")]
BufferNotFound(BufferID),
+ #[error("Function {0} has no dyadic form")]
+ NoDyadicForm(&'static str),
}
-struct SFComponents {
- niladic: Box<dyn for<'a> Fn(&'a EditorState) -> Result<Selection, SFError>>,
- monadic_rank0:
- Box<dyn for<'a> Fn(&'a EditorState, BufferID, usize) -> Result<Selection, SFError>>,
- monadic_rank1: Box<
- dyn for<'a, 'b> Fn(&'a EditorState, BufferID, &'b Interval) -> Result<Selection, SFError>,
- >,
- dyadic: Option<
- Box<
- dyn for<'a, 'b, 'c> Fn(
- &'a EditorState,
- &'b Selection,
- &'c Selection,
- ) -> Result<Selection, SFError>,
- >,
- >,
+pub enum SFArguments<'a> {
+ Niladic {
+ es: &'a EditorState,
+ },
+ Monadic {
+ es: &'a EditorState,
+ left: Selection,
+ },
+ Dyadic {
+ es: &'a EditorState,
+ left: Selection,
+ right: Selection,
+ },
}
-pub struct SelectionFunction<E> {
- niladic: Box<dyn for<'a> Fn(&'a EditorState) -> Result<Selection, E>>,
- monadic: Box<dyn for<'a, 'b> Fn(&'a EditorState, &'b Selection) -> Result<Selection, E>>,
- dyadic: Option<
- Box<
- dyn for<'a, 'b, 'c> Fn(
- &'a EditorState,
- &'b Selection,
- &'c Selection,
- ) -> Result<Selection, E>,
- >,
- >,
-}
+type SFResult = Result<Selection, VectoriseError<SFError>>;
-impl From<SFComponents> for SelectionFunction<VectoriseError<SFError>> {
- fn from(sfc: SFComponents) -> Self {
- let dyadic: Option<
- Box<dyn for<'a, 'b, 'c> Fn(&'a EditorState, &'b Selection, &'c Selection) -> _>,
- > = if let Some(func) = sfc.dyadic {
- Some(Box::new(
- move |editor_state: &EditorState, left: &Selection, right: &Selection| {
- (func)(editor_state, left, right).map_err(VectoriseError::ProcessingError)
- },
- ))
- } else {
- None
- };
- let niladic: Box<dyn for<'a> Fn(&'a EditorState) -> _> =
- Box::new(move |editor_state: &EditorState| {
- (sfc.niladic)(editor_state).map_err(VectoriseError::ProcessingError)
- });
- let monadic: Box<dyn for<'a, 'b> Fn(&'a EditorState, &'b Selection) -> _> =
- Box::new(move |es, left| {
- Selection::vectorise(&*sfc.monadic_rank0, &*sfc.monadic_rank1, es, left)
- });
- Self {
- niladic,
- monadic,
- dyadic,
- }
- }
+fn rust_has_an_annoying_issue(r: Result<Selection, SFError>) -> SFResult {
+ r.map_err(Into::into)
}
-impl SelectionFunction<VectoriseError<SFError>> {
- pub fn transform_conditional(sf: Self) -> Self {
- fn condition(mut pred: Selection, res: Selection) -> Selection {
- if pred.is_empty() {
- pred
- } else {
- res
- }
- }
-
- let dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<_, _>>> =
- if let Some(dyadic) = sf.dyadic {
- Some(Box::new(move |es, left, right| {
- Ok(condition((dyadic)(es, left, right)?, left.clone()))
- }))
- } else {
- None
- };
-
- let monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<_, _>> =
- Box::new(move |es, left| Ok(condition((sf.monadic)(es, left)?, left.clone())));
-
- SelectionFunction {
- niladic: sf.niladic,
- monadic,
- dyadic,
- }
- }
-
- pub fn complement_transform(sf: Self) -> Self {
- fn complement_rank0(
- es: &EditorState,
- buffer_id: BufferID,
- pos: usize,
- ) -> Result<Selection, SFError> {
- if let Some(buf) = es.get_buffer(buffer_id) {
- let mut ranges = Vec::new();
- if pos > 0 {
- ranges.push(Interval::new(0, pos));
- }
- let max_pos = buf.max_pos();
- if pos + 1 < max_pos {
- ranges.push(Interval::new(pos + 1, max_pos));
+macro_rules! selection_function {
+ (
+ name: $name:ident,
+ niladic: $niladic_body:expr,
+ monadic_rank0: $monadic_rank0_body:expr,
+ monadic_rank1: $monadic_rank1_body:expr
+ ) => {
+ pub fn $name(arg: SFArguments) -> SFResult {
+ match arg {
+ SFArguments::Niladic { es } => rust_has_an_annoying_issue({ $niladic_body(es) }),
+ SFArguments::Monadic { es, left } => {
+ left.vectorise(es, $monadic_rank0_body, $monadic_rank1_body)
}
- Ok(Selection::Ranges { buffer_id, ranges })
- } else {
- Err(SFError::BufferNotFound(buffer_id))
+ SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()),
}
}
+ };
+}
- fn complement_rank1(
- es: &EditorState,
- buffer_id: BufferID,
- interval: &Interval,
- ) -> Result<Selection, SFError> {
- if let Some(buf) = es.get_buffer(buffer_id) {
- let max_pos = buf.max_pos();
- if interval.start == 0 && interval.end >= max_pos {
- return Ok(Selection::empty());
- }
-
- let mut ranges = Vec::new();
- if interval.start == 0 {
- if interval.end < max_pos {
- ranges.push(Interval::new(interval.end, max_pos));
- }
- } else if interval.end == max_pos {
- ranges.push(Interval::new(0, interval.start));
- } else {
- ranges.push(Interval::new(0, interval.start));
- ranges.push(Interval::new(interval.end, max_pos));
- }
- Ok(Selection::Ranges { buffer_id, ranges })
- } else {
- Err(SFError::BufferNotFound(buffer_id))
- }
- }
-
- fn complement(
- es: &EditorState,
- selection: Selection,
- ) -> Result<Selection, VectoriseError<SFError>> {
- Selection::vectorise(complement_rank0, complement_rank1, es, &selection)
- }
-
- let dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<_, _>>> =
- if let Some(dyadic) = sf.dyadic {
- Some(Box::new(move |es, left, right| {
- complement(es, (dyadic)(es, left, right)?)
- }))
- } else {
- None
- };
-
- let monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<_, _>> =
- Box::new(move |es, left| complement(es, (sf.monadic)(es, left)?));
+// ----------------------------------------------------------------
- let niladic: Box<dyn Fn(&EditorState) -> Result<_, _>> =
- Box::new(move |es| complement(es, (sf.niladic)(es)?));
+pub fn empty_sequential(_: SFArguments) -> SFResult {
+ Ok(Selection::empty())
+}
- SelectionFunction {
- niladic,
- monadic,
- dyadic,
- }
- }
- // ----------------------------------------------------------------
- pub fn empty_sequential() -> Self {
- SFComponents {
- niladic: Box::new(|_| Ok(Selection::empty())),
- monadic_rank0: Box::new(|_, _, _| Ok(Selection::empty())),
- monadic_rank1: Box::new(|_, _, _| Ok(Selection::empty())),
- dyadic: None,
- }
- .into()
- }
+pub fn empy_structural(_: SFArguments) -> SFResult {
+ Ok(Selection::empty())
+}
- pub fn empy_structural() -> Self {
- Self::empty_sequential()
+selection_function! {
+ name: end_sequential,
+ niladic: |es: &EditorState| {
+ es.current_buffer().map(|buf| Selection::Position {
+ buffer_id: es.current_buffer_id,
+ pos: buf.max_pos()
+ }).ok_or(SFError::BufferNotFound(es.current_buffer_id))
+ },
+ monadic_rank0: |_, buffer_id, pos| {
+ Ok(Selection::Position { buffer_id, pos })
+ },
+ monadic_rank1: |_, buffer_id, interval| {
+ Ok(Selection::Position {
+ buffer_id,
+ pos: interval.end,
+ })
}
+}
- pub fn end_sequential() -> Self {
- fn get_end_position(es: &EditorState, buffer_id: BufferID) -> Result<Selection, SFError> {
- if let Some(buf) = es.get_buffer(buffer_id) {
+selection_function! {
+ name: end_structural,
+ niladic: |es: &EditorState| {
+ if let Some(buf) = es.current_buffer() {
Ok(Selection::Position {
- buffer_id: buffer_id,
+ buffer_id: es.current_buffer_id,
pos: buf.max_pos(),
})
} else {
- Err(SFError::BufferNotFound(buffer_id))
+ Err(SFError::BufferNotFound(es.current_buffer_id).into())
}
- }
-
- SFComponents {
- niladic: Box::new(|es| get_end_position(es, es.current_buffer_id)),
- monadic_rank0: Box::new(|es, buffer_id, _| get_end_position(es, buffer_id)),
- monadic_rank1: Box::new(|es, buffer_id, _| get_end_position(es, buffer_id)),
- dyadic: None,
- }
- .into()
- }
-
- pub fn end_structural() -> Self {
- SFComponents {
- niladic: Box::new(|es| {
- if let Some(buf) = es.current_buffer() {
- Ok(Selection::Position {
- buffer_id: es.current_buffer_id,
- pos: buf.max_pos(),
- })
- } else {
- Err(SFError::BufferNotFound(es.current_buffer_id))
- }
- }),
- monadic_rank0: Box::new(|_, buffer_id, pos| Ok(Selection::Position { buffer_id, pos })),
- monadic_rank1: Box::new(|_, buffer_id, int| {
- Ok(Selection::Position {
- buffer_id,
- pos: int.end,
- })
- }),
- dyadic: None,
- }
- .into()
- }
+ },
+ monadic_rank0: |_, buffer_id, pos | Ok(Selection::Position { buffer_id, pos }),
+ monadic_rank1: |_, buffer_id, int | Ok(Selection::Position {
+ buffer_id,
+ pos: int.end,
+ })
}
+
+// pub fn transform_conditional(sf: Self) -> Self {
+// fn condition(mut pred: Selection, res: Selection) -> Selection {
+// if pred.is_empty() {
+// pred
+// } else {
+// res
+// }
+// }
+
+// let dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<_, _>>> =
+// if let Some(dyadic) = sf.dyadic {
+// Some(Box::new(move |es, left, right| {
+// Ok(condition((dyadic)(es, left, right)?, left.clone()))
+// }))
+// } else {
+// None
+// };
+
+// let monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<_, _>> =
+// Box::new(move |es, left| Ok(condition((sf.monadic)(es, left)?, left.clone())));
+
+// SelectionFunction {
+// niladic: sf.niladic,
+// monadic,
+// dyadic,
+// }
+// }
+
+// pub fn complement_transform(sf: Self) -> Self {
+// fn complement_rank0(
+// es: &EditorState,
+// buffer_id: BufferID,
+// pos: usize,
+// ) -> Result<Selection, SFError> {
+// if let Some(buf) = es.get_buffer(buffer_id) {
+// let mut ranges = Vec::new();
+// if pos > 0 {
+// ranges.push(Interval::new(0, pos));
+// }
+// let max_pos = buf.max_pos();
+// if pos + 1 < max_pos {
+// ranges.push(Interval::new(pos + 1, max_pos));
+// }
+// Ok(Selection::Ranges { buffer_id, ranges })
+// } else {
+// Err(SFError::BufferNotFound(buffer_id))
+// }
+// }
+
+// fn complement_rank1(
+// es: &EditorState,
+// buffer_id: BufferID,
+// interval: &Interval,
+// ) -> Result<Selection, SFError> {
+// if let Some(buf) = es.get_buffer(buffer_id) {
+// let max_pos = buf.max_pos();
+// if interval.start == 0 && interval.end >= max_pos {
+// return Ok(Selection::empty());
+// }
+
+// let mut ranges = Vec::new();
+// if interval.start == 0 {
+// if interval.end < max_pos {
+// ranges.push(Interval::new(interval.end, max_pos));
+// }
+// } else if interval.end == max_pos {
+// ranges.push(Interval::new(0, interval.start));
+// } else {
+// ranges.push(Interval::new(0, interval.start));
+// ranges.push(Interval::new(interval.end, max_pos));
+// }
+// Ok(Selection::Ranges { buffer_id, ranges })
+// } else {
+// Err(SFError::BufferNotFound(buffer_id))
+// }
+// }
+
+// fn complement(
+// es: &EditorState,
+// selection: Selection,
+// ) -> Result<Selection, VectoriseError<SFError>> {
+// Selection::vectorise(complement_rank0, complement_rank1, es, &selection)
+// }
+
+// let dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<_, _>>> =
+// if let Some(dyadic) = sf.dyadic {
+// Some(Box::new(move |es, left, right| {
+// complement(es, (dyadic)(es, left, right)?)
+// }))
+// } else {
+// None
+// };
+
+// let monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<_, _>> =
+// Box::new(move |es, left| complement(es, (sf.monadic)(es, left)?));
+
+// let niladic: Box<dyn Fn(&EditorState) -> Result<_, _>> =
+// Box::new(move |es| complement(es, (sf.niladic)(es)?));
+
+// SelectionFunction {
+// niladic,
+// monadic,
+// dyadic,
+// }
+// }