diff options
Diffstat (limited to 'rprt-engine/src/selection.rs')
| -rw-r--r-- | rprt-engine/src/selection.rs | 110 |
1 files changed, 57 insertions, 53 deletions
diff --git a/rprt-engine/src/selection.rs b/rprt-engine/src/selection.rs index c15512d..ee83294 100644 --- a/rprt-engine/src/selection.rs +++ b/rprt-engine/src/selection.rs @@ -45,15 +45,15 @@ impl Interval { #[derive(Debug, Clone)] pub enum Selection { Position { + buffer_id: BufferID, pos: usize, - buffer: BufferID, }, Range { - buffer: BufferID, + buffer_id: BufferID, interval: Interval, }, Ranges { - buffer: BufferID, + buffer_id: BufferID, ranges: Vec<Interval>, }, MultiRanges { @@ -91,33 +91,23 @@ impl Selection { } } - pub fn ranges_disjoint(ranges: &[Interval]) -> bool { - if ranges.len() < 1 { - return true; + fn normalise(&mut self) { + if let Self::MultiRanges { multi_ranges } = self { + multi_ranges.retain(|_, v| !v.is_empty()) } - - let mut sorted_by_start: Vec<&Interval> = ranges.iter().collect::<Vec<_>>(); - sorted_by_start.sort_by_key(|i| i.start); - sorted_by_start.windows(2).all(|w| w[0].is_disjoint(&w[1])) } - pub fn is_disjoint(&self) -> bool { + pub fn is_empty(&mut self) -> bool { + self.normalise(); match self { - Self::Position { .. } => true, - Self::Range { .. } => true, - Self::Ranges { ranges, .. } => Self::ranges_disjoint(ranges), - Self::MultiRanges { multi_ranges } => { - for (_, intervals) in multi_ranges { - if !Self::ranges_disjoint(intervals) { - return false; - } - } - true - } + Self::Position { .. } => return false, + Self::Range { .. } => return false, + Self::Ranges { ranges, .. } => ranges.is_empty(), + Self::MultiRanges { multi_ranges } => multi_ranges.is_empty(), } } - pub fn rank(&self) -> Rank { + fn rank(&self) -> Rank { match self { Self::Position { .. } => Rank::Zero, Self::Range { .. } => Rank::One, @@ -126,7 +116,7 @@ impl Selection { } } - pub fn promote(&self, to_rank: Rank) -> Result<Self, SelectionError> { + fn promote(&self, to_rank: Rank) -> Result<Self, SelectionError> { use Rank::*; match (self, to_rank) { @@ -136,26 +126,26 @@ impl Selection { (Self::MultiRanges { .. }, Three) => Ok(self.clone()), // Position - (Self::Position { pos, buffer }, One) => Ok(Self::Range { + (Self::Position { pos, buffer_id }, One) => Ok(Self::Range { interval: Interval { start: pos + 0, end: pos + 1, capture_groups: Vec::new(), }, - buffer: *buffer, + buffer_id: *buffer_id, }), - (Self::Position { pos, buffer }, Two) => Ok(Self::Ranges { + (Self::Position { pos, buffer_id }, Two) => Ok(Self::Ranges { ranges: vec![Interval { start: pos + 0, end: pos + 1, capture_groups: Vec::new(), }], - buffer: *buffer, + buffer_id: *buffer_id, }), - (Self::Position { pos, buffer }, Three) => { + (Self::Position { pos, buffer_id }, Three) => { let mut map = HashMap::new(); map.insert( - *buffer, + *buffer_id, vec![Interval { start: pos + 0, end: pos + 1, @@ -166,20 +156,32 @@ impl Selection { } // Range promotions - (Self::Range { interval, buffer }, Two) => Ok(Self::Ranges { + ( + Self::Range { + interval, + buffer_id, + }, + Two, + ) => Ok(Self::Ranges { ranges: vec![interval.clone()], - buffer: *buffer, + buffer_id: *buffer_id, }), - (Self::Range { interval, buffer }, Three) => { + ( + Self::Range { + interval, + buffer_id, + }, + Three, + ) => { let mut map = HashMap::new(); - map.insert(*buffer, vec![interval.clone()]); + map.insert(*buffer_id, vec![interval.clone()]); Ok(Self::MultiRanges { multi_ranges: map }) } // Ranges promotion - (Self::Ranges { ranges, buffer }, Three) => { + (Self::Ranges { ranges, buffer_id }, Three) => { let mut map = HashMap::new(); - map.insert(*buffer, ranges.clone()); + map.insert(*buffer_id, ranges.clone()); Ok(Self::MultiRanges { multi_ranges: map }) } @@ -191,11 +193,11 @@ impl Selection { } } - pub fn buffers(&self) -> Vec<BufferID> { + fn buffers(&self) -> Vec<BufferID> { match self { - Self::Position { buffer, .. } => vec![*buffer], - Self::Range { buffer, .. } => vec![*buffer], - Self::Ranges { buffer, .. } => vec![*buffer], + Self::Position { buffer_id, .. } => vec![*buffer_id], + Self::Range { buffer_id, .. } => vec![*buffer_id], + Self::Ranges { buffer_id, .. } => vec![*buffer_id], Self::MultiRanges { multi_ranges } => multi_ranges.keys().copied().collect(), } } @@ -229,7 +231,7 @@ impl Selection { match max_rank { Rank::Two => { let mut all_intervals = Vec::new(); - let buffer = *all_buffers.iter().next().unwrap(); + let buffer_id = *all_buffers.iter().next().unwrap(); for sel in &promoted { match sel { @@ -240,7 +242,7 @@ impl Selection { Ok(Self::Ranges { ranges: all_intervals, - buffer, + buffer_id, }) } Rank::Three => { @@ -272,8 +274,8 @@ 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, + 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>> where E: std::error::Error + 'static, @@ -281,27 +283,29 @@ impl Selection { // look at this mess! use VectoriseError::{ProcessingError, SelectionError}; move |state: &S, selection: &Selection| { - let do_rank_one = |b: &usize, rs: &Vec<Interval>| { + 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, pos } => { - fn_rank_zero(state, buffer, *pos).map_err(ProcessingError) - } - Self::Range { buffer, interval } => { - fn_rank_one(state, buffer, interval).map_err(VectoriseError::ProcessingError) + &Self::Position { buffer_id, pos } => { + fn_rank_zero(state, buffer_id, pos).map_err(ProcessingError) } - Self::Ranges { buffer, ranges } => { - let results = do_rank_one(buffer, ranges)?; + 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, ranges)| do_rank_one(buffer, ranges)) + .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(); |
