diff options
| author | tslil <tslil@posteo.de> | 2025-10-23 20:58:39 +0100 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2025-10-23 21:58:20 +0100 |
| commit | 7c36fb82df24cfa96ad2d2bf3fa769142c178fc1 (patch) | |
| tree | 036e2b076c80a1b3dcd5183258bb56a6ca997969 /rprt-engine/src/selection.rs | |
| parent | 1a109e4d6bcc348607859342b144daef11c124cd (diff) | |
One painful manual currying and Higher Rank Trait Bounds application later, i think complement transformations work now
Diffstat (limited to 'rprt-engine/src/selection.rs')
| -rw-r--r-- | rprt-engine/src/selection.rs | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/rprt-engine/src/selection.rs b/rprt-engine/src/selection.rs index 1d1c557..9e619a4 100644 --- a/rprt-engine/src/selection.rs +++ b/rprt-engine/src/selection.rs @@ -37,6 +37,14 @@ pub struct Interval { } impl Interval { + pub fn new(start: usize, end: usize) -> Self { + Self { + start, + end, + capture_groups: Vec::new(), + } + } + pub fn is_disjoint(&self, other: &Interval) -> bool { self.start >= other.end || self.end <= other.start } @@ -61,7 +69,7 @@ pub enum Selection { }, } -// rust is stupid and i have to make a wrapper class and worse still _other +// rust is ... sigh. I have to make a wrapper class and worse still _other // people_ have to deal with my wrapper class! #[derive(Error, Debug)] pub enum VectoriseError<E> @@ -265,43 +273,42 @@ impl Selection { } pub fn vectorise<S, E>( - fn_rank_zero: impl Fn(&S, BufferID, usize) -> Result<Selection, E> + 'static, - fn_rank_one: impl Fn(&S, BufferID, &Interval) -> Result<Selection, E> + 'static, - ) -> impl Fn(&S, &Selection) -> Result<Selection, VectoriseError<E>> + fn_rank_zero: impl Fn(&S, BufferID, usize) -> Result<Selection, E>, + fn_rank_one: impl Fn(&S, BufferID, &Interval) -> Result<Selection, E>, + state: &S, + selection: &Selection, + ) -> Result<Selection, VectoriseError<E>> where E: std::error::Error + 'static, { // look at this mess! use VectoriseError::{ProcessingError, SelectionError}; - move |state: &S, selection: &Selection| { - let do_rank_one = |b: usize, rs: &Vec<Interval>| { - rs.iter() - .map(|int| fn_rank_one(state, b, int).map_err(ProcessingError)) - .collect::<Result<_, _>>() - }; - - match selection { - &Self::Position { buffer_id, pos } => { - fn_rank_zero(state, buffer_id, pos).map_err(ProcessingError) - } - Self::Range { - interval, - buffer_id, - } => fn_rank_one(state, *buffer_id, interval) - .map_err(VectoriseError::ProcessingError), - Self::Ranges { buffer_id, ranges } => { - let results = do_rank_one(*buffer_id, ranges)?; - Self::union(results).map_err(SelectionError) - } - Self::MultiRanges { multi_ranges } => { - let all_ok: Vec<Vec<Self>> = multi_ranges - .iter() - .map(|(buffer_id, ranges)| do_rank_one(*buffer_id, ranges)) - .collect::<Result<_, _>>()?; - // It would seem that Rust has no built in monadic flatten, or in general cannot lift things to operate on Result... :( - let results: Vec<Self> = all_ok.into_iter().flatten().collect(); - Self::union(results).map_err(SelectionError) - } + let do_rank_one = |b: usize, rs: &Vec<Interval>| { + rs.iter() + .map(|int| fn_rank_one(state, b, int).map_err(ProcessingError)) + .collect::<Result<_, _>>() + }; + + match selection { + &Self::Position { buffer_id, pos } => { + fn_rank_zero(state, buffer_id, pos).map_err(ProcessingError) + } + Self::Range { + interval, + buffer_id, + } => fn_rank_one(state, *buffer_id, interval).map_err(VectoriseError::ProcessingError), + Self::Ranges { buffer_id, ranges } => { + let results = do_rank_one(*buffer_id, ranges)?; + Self::union(results).map_err(SelectionError) + } + Self::MultiRanges { multi_ranges } => { + let all_ok: Vec<Vec<Self>> = multi_ranges + .iter() + .map(|(buffer_id, ranges)| do_rank_one(*buffer_id, ranges)) + .collect::<Result<_, _>>()?; + // It would seem that Rust has no built in monadic flatten, or in general cannot lift things to operate on Result... :( + let results: Vec<Self> = all_ok.into_iter().flatten().collect(); + Self::union(results).map_err(SelectionError) } } } |
