X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=rust%2Fsrc%2Fdictionary.rs;h=f9886641f7f582398627b9ab937cf63b1ab8caa3;hb=ad10c0fc07a3183f0a991b23d7523023baa9a098;hp=fd408d7725c7345fcc8959facd9a61bd152d626e;hpb=98eeb0ffdd812543c011752cfb74e375cbf715ba;p=pspp diff --git a/rust/src/dictionary.rs b/rust/src/dictionary.rs index fd408d7725..f9886641f7 100644 --- a/rust/src/dictionary.rs +++ b/rust/src/dictionary.rs @@ -1,16 +1,17 @@ use std::{ collections::{HashMap, HashSet}, fmt::Debug, + ops::{Bound, RangeBounds}, }; use encoding_rs::Encoding; use indexmap::IndexSet; use crate::{ - cooked::{Alignment, Measure, MissingValues, Value, VarWidth}, + cooked::{MissingValues, Value, VarWidth}, format::Format, identifier::{ByIdentifier, HasIdentifier, Identifier}, - raw::CategoryLabels, + raw::{CategoryLabels, Alignment, Measure}, }; pub type DictIndex = usize; @@ -49,16 +50,77 @@ impl Dictionary { } } - 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(&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(&mut self, range: R) + where + R: RangeBounds, + { + 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(&mut self, f: &F)