use crate::buffer::BufferID; use crate::selection::{Selection, VectoriseError}; use crate::state::EditorState; use thiserror::Error; #[derive(Error, Debug)] pub enum SFError { #[error("Could not find buffer {0}")] BufferNotFound(BufferID), #[error("Function {0} has no dyadic form")] NoDyadicForm(&'static str), } pub enum SFArguments<'a> { Niladic { es: &'a EditorState, }, Monadic { es: &'a EditorState, left: Selection, }, Dyadic { es: &'a EditorState, left: Selection, right: Selection, }, } type SFResult = Result>; fn rust_has_an_annoying_issue(r: Result) -> SFResult { r.map_err(Into::into) } 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) } SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()), } } }; } // ---------------------------------------------------------------- pub fn empty_sequential(_: SFArguments) -> SFResult { Ok(Selection::empty()) } pub fn empy_structural(_: SFArguments) -> SFResult { Ok(Selection::empty()) } 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, }) } } selection_function! { name: end_structural, niladic: |es: &EditorState| { 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).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 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, // } // }