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 Result>, monadic_rank0: Box Result>, monadic_rank1: Box Result>, dyadic: Option Result>>, } pub struct SelectionFunction { niladic: Box Result>, monadic: Box Result>, dyadic: Option Result>>, } impl From for SelectionFunction> { fn from(sfc: SFComponents) -> Self { let dyadic: Option _>> = 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)); Self { niladic, monadic, dyadic, } } } impl SelectionFunction> { pub fn transform_conditional(sf: Self) -> Self { fn condition( pred: Result>, res: Selection, ) -> Result> { match pred { Ok(mut sel) => Ok(if sel.is_empty() { sel } else { res }), Err(e) => Err(e), } } let dyadic: Option Result<_, _>>> = if let Some(dyadic) = sf.dyadic { Some(Box::new(move |es, left, right| { condition((dyadic)(es, left, right), left.clone()) })) } else { None }; let monadic: Box Result<_, _>> = Box::new(move |es, left| condition((sf.monadic)(es, left), left.clone())); SelectionFunction { niladic: sf.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() } }