use crate::buffer::BufferID; use crate::selection::{Interval, Selection, VectoriseError}; use crate::state::EditorState; use thiserror::Error; #[derive(Error, Debug)] pub enum SFError { #[error("Could not find buffer {0}")] BufferNotFound(BufferID), } struct SFComponents { niladic: Box Fn(&'a EditorState) -> Result>, monadic_rank0: Box Fn(&'a EditorState, BufferID, usize) -> Result>, monadic_rank1: Box< dyn for<'a, 'b> Fn(&'a EditorState, BufferID, &'b Interval) -> Result, >, dyadic: Option< Box< dyn for<'a, 'b, 'c> Fn( &'a EditorState, &'b Selection, &'c Selection, ) -> Result, >, >, } pub struct SelectionFunction { niladic: Box Fn(&'a EditorState) -> Result>, monadic: Box Fn(&'a EditorState, &'b Selection) -> Result>, dyadic: Option< Box< dyn for<'a, 'b, 'c> Fn( &'a EditorState, &'b Selection, &'c Selection, ) -> Result, >, >, } impl From for SelectionFunction> { fn from(sfc: SFComponents) -> Self { let dyadic: Option< Box 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 Fn(&'a EditorState) -> _> = Box::new(move |editor_state: &EditorState| { (sfc.niladic)(editor_state).map_err(VectoriseError::ProcessingError) }); let monadic: Box Fn(&'a EditorState, &'b Selection) -> _> = Box::new(move |es, left| { Selection::vectorise(&*sfc.monadic_rank0, &*sfc.monadic_rank1, es, left) }); Self { niladic, monadic, dyadic, } } } impl SelectionFunction> { 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 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 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 { 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 { 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::vectorise(complement_rank0, complement_rank1, es, &selection) } let dyadic: Option 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 Result<_, _>> = Box::new(move |es, left| complement(es, (sf.monadic)(es, left)?)); let niladic: Box Result<_, _>> = Box::new(move |es| complement(es, (sf.niladic)(es)?)); 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() -> Self { Self::empty_sequential() } pub fn end_sequential() -> Self { fn get_end_position(es: &EditorState, buffer_id: BufferID) -> Result { if let Some(buf) = es.get_buffer(buffer_id) { Ok(Selection::Position { buffer_id: buffer_id, pos: buf.max_pos(), }) } else { Err(SFError::BufferNotFound(buffer_id)) } } 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() } }