use std::collections::HashSet;
pub trait MultiSelectIndexStorage {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn is_selected(&self, index: usize) -> bool;
fn set_selected(&mut self, index: usize, selected: bool);
fn selected_count_hint(&self) -> Option<usize> {
None
}
}
impl MultiSelectIndexStorage for Vec<bool> {
fn len(&self) -> usize {
self.len()
}
fn is_selected(&self, index: usize) -> bool {
self.get(index).copied().unwrap_or(false)
}
fn set_selected(&mut self, index: usize, selected: bool) {
if index < self.len() {
self[index] = selected;
}
}
fn selected_count_hint(&self) -> Option<usize> {
Some(self.iter().filter(|&&b| b).count())
}
}
impl MultiSelectIndexStorage for &mut [bool] {
fn len(&self) -> usize {
(**self).len()
}
fn is_selected(&self, index: usize) -> bool {
self.get(index).copied().unwrap_or(false)
}
fn set_selected(&mut self, index: usize, selected: bool) {
if index < self.len() {
self[index] = selected;
}
}
fn selected_count_hint(&self) -> Option<usize> {
Some(self.iter().filter(|&&b| b).count())
}
}
pub struct KeySetSelection<'a, K>
where
K: Eq + std::hash::Hash + Copy,
{
keys: &'a [K],
selected: &'a mut HashSet<K>,
}
impl<'a, K> KeySetSelection<'a, K>
where
K: Eq + std::hash::Hash + Copy,
{
pub fn new(keys: &'a [K], selected: &'a mut HashSet<K>) -> Self {
Self { keys, selected }
}
}
impl<'a, K> MultiSelectIndexStorage for KeySetSelection<'a, K>
where
K: Eq + std::hash::Hash + Copy,
{
fn len(&self) -> usize {
self.keys.len()
}
fn is_selected(&self, index: usize) -> bool {
self.keys
.get(index)
.map(|k| self.selected.contains(k))
.unwrap_or(false)
}
fn set_selected(&mut self, index: usize, selected: bool) {
if let Some(&key) = self.keys.get(index) {
if selected {
self.selected.insert(key);
} else {
self.selected.remove(&key);
}
}
}
fn selected_count_hint(&self) -> Option<usize> {
Some(self.selected.len())
}
}