diff options
Diffstat (limited to 'rprt-engine/src')
| -rw-r--r-- | rprt-engine/src/selection.rs | 17 | ||||
| -rw-r--r-- | rprt-engine/src/selection_function.rs | 384 |
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, +// } +// } |
