aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine/src/selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rprt-engine/src/selection.rs')
-rw-r--r--rprt-engine/src/selection.rs110
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();