use std::{
collections::{HashMap, HashSet},
fmt::Debug,
+ ops::{Bound, RangeBounds},
};
use encoding_rs::Encoding;
}
}
- pub fn delete_vars(&mut self, start: DictIndex, count: usize) {
- self.update_dict_indexes(&|index| {
- if index < start {
- Some(index)
- } else if index < start + count {
- None
- } else {
- Some(index - count)
+ pub fn reorder_var(&mut self, from_index: DictIndex, to_index: DictIndex) {
+ if from_index != to_index {
+ self.variables.move_index(from_index, to_index);
+ self.update_dict_indexes(&|index| {
+ if index == from_index {
+ Some(to_index)
+ } else if from_index < to_index {
+ if index > from_index && index <= to_index {
+ Some(index - 1)
+ } else {
+ Some(index)
+ }
+ } else {
+ if index >= to_index && index < from_index {
+ Some(index + 1)
+ } else {
+ Some(index)
+ }
+ }
+ })
+ }
+ }
+
+ pub fn retain_vars<F>(&mut self, keep: F)
+ where
+ F: Fn(&Variable) -> bool,
+ {
+ let mut deleted = Vec::new();
+ let mut index = 0;
+ self.variables.retain(|var_by_id| {
+ let keep = keep(&var_by_id.0);
+ if !keep {
+ deleted.push(index);
}
- })
+ index += 1;
+ keep
+ });
+ if !deleted.is_empty() {
+ self.update_dict_indexes(&|index| match deleted.binary_search(&index) {
+ Ok(_) => None,
+ Err(position) => Some(position),
+ })
+ }
+ }
+
+ pub fn delete_vars<R>(&mut self, range: R)
+ where
+ R: RangeBounds<DictIndex>,
+ {
+ let start = match range.start_bound() {
+ Bound::Included(&start) => start,
+ Bound::Excluded(&start) => start + 1,
+ Bound::Unbounded => 0,
+ };
+ let end = match range.end_bound() {
+ Bound::Included(&end) => end + 1,
+ Bound::Excluded(&end) => end,
+ Bound::Unbounded => self.variables.len(),
+ };
+ if end > start {
+ self.variables.drain(start..end);
+ self.update_dict_indexes(&|index| {
+ if index < start {
+ Some(index)
+ } else if index < end {
+ None
+ } else {
+ Some(index - end - start)
+ }
+ })
+ }
}
fn update_dict_indexes<F>(&mut self, f: &F)