diff options
Diffstat (limited to 'rprt-engine/src/selection_function.rs')
| -rw-r--r-- | rprt-engine/src/selection_function.rs | 160 |
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 { |
