aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine/src/selection_function.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rprt-engine/src/selection_function.rs')
-rw-r--r--rprt-engine/src/selection_function.rs160
1 files changed, 130 insertions, 30 deletions
diff --git a/rprt-engine/src/selection_function.rs b/rprt-engine/src/selection_function.rs
index 0b6e98e..67f6ccc 100644
--- a/rprt-engine/src/selection_function.rs
+++ b/rprt-engine/src/selection_function.rs
@@ -10,34 +10,58 @@ pub enum SFError {
}
struct SFComponents {
- niladic: Box<dyn Fn(&EditorState) -> Result<Selection, SFError>>,
- monadic_rank0: Box<dyn Fn(&EditorState, BufferID, usize) -> Result<Selection, SFError>>,
- monadic_rank1: Box<dyn Fn(&EditorState, BufferID, &Interval) -> Result<Selection, SFError>>,
- dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<Selection, SFError>>>,
+ 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 struct SelectionFunction<E> {
- niladic: Box<dyn Fn(&EditorState) -> Result<Selection, E>>,
- monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<Selection, E>>,
- dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &Selection) -> Result<Selection, 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>,
+ >,
+ >,
}
impl From<SFComponents> for SelectionFunction<VectoriseError<SFError>> {
fn from(sfc: SFComponents) -> Self {
- let dyadic: Option<Box<dyn Fn(&EditorState, &Selection, &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::new(move |editor_state: &EditorState| {
- (sfc.niladic)(editor_state).map_err(VectoriseError::ProcessingError)
- });
- let monadic = Box::new(Selection::vectorise(sfc.monadic_rank0, sfc.monadic_rank1));
+ 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,
@@ -48,27 +72,25 @@ impl From<SFComponents> for SelectionFunction<VectoriseError<SFError>> {
impl SelectionFunction<VectoriseError<SFError>> {
pub fn transform_conditional(sf: Self) -> Self {
- fn condition(
- pred: Result<Selection, VectoriseError<SFError>>,
- res: Selection,
- ) -> Result<Selection, VectoriseError<SFError>> {
- match pred {
- Ok(mut sel) => Ok(if sel.is_empty() { sel } else { res }),
- Err(e) => Err(e),
+ 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| {
- condition((dyadic)(es, left, right), left.clone())
+ Ok(condition((dyadic)(es, left, right)?, left.clone()))
}))
} else {
None
};
let monadic: Box<dyn Fn(&EditorState, &Selection) -> Result<_, _>> =
- Box::new(move |es, left| condition((sf.monadic)(es, left), left.clone()));
+ Box::new(move |es, left| Ok(condition((sf.monadic)(es, left)?, left.clone())));
SelectionFunction {
niladic: sf.niladic,
@@ -76,6 +98,84 @@ impl SelectionFunction<VectoriseError<SFError>> {
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,
+ }
+ }
// ----------------------------------------------------------------
pub fn empty_sequential() -> Self {
SFComponents {