1use crate::{Identifier, Selection};
2use indexmap::IndexMap;
3use rustc_hash::FxBuildHasher;
4use std::sync::Mutex;
5use std::{borrow::Borrow, hash::Hash, sync::Arc};
6
7pub type SelectionValidator<S> = fn(&S) -> bool;
8#[derive(Debug)]
9pub struct Selector<T, S> {
10 selections: SelectorImpl<u32, S>,
11 pub identifier: Identifier<T, S>,
12 pub validator: SelectionValidator<S>,
13}
14
15pub fn truthy_validator<S>(_: &S) -> bool {
16 true
17}
18
19impl<T, S: Selection> Selector<T, S> {
20 pub fn new(identifier: Identifier<T, S>) -> Self {
21 Self::new_with_validator(identifier, truthy_validator)
22 }
23
24 pub fn new_with_validator(
25 identifier: Identifier<T, S>,
26 validator: SelectionValidator<S>,
27 ) -> Self {
28 Self {
29 selections: SelectorImpl::new(),
30 identifier,
31 validator,
32 }
33 }
34
35 pub fn sel(&mut self, item: &T) -> bool {
36 let (k, v) = (self.identifier)(item);
37 self.selections.insert(k, v)
38 }
39
40 pub fn desel(&mut self, item: &T) -> bool {
41 let (k, _v) = (self.identifier)(item);
42 self.selections.remove(&k)
43 }
44
45 pub fn contains(&self, item: &T) -> bool {
46 let (k, _v) = (self.identifier)(item);
47 self.selections.contains(&k)
48 }
49
50 pub fn toggle(&mut self, item: &T) {
51 let (k, v) = (self.identifier)(item);
52 if self.selections.contains(&k) {
53 self.selections.remove(&k);
54 } else {
55 self.selections.insert(k, v);
56 }
57 }
58
59 pub fn clear(&mut self) {
60 self.selections.clear();
61 }
62
63 pub fn len(&self) -> usize {
64 self.selections.len()
65 }
66
67 pub fn is_empty(&self) -> bool {
68 self.selections.is_empty()
69 }
70
71 pub fn output(&mut self) -> impl Iterator<Item = S>
72{
74 let mut set = self.selections.set.lock().unwrap();
75
76 std::mem::take(&mut *set).into_values()
77 }
78
79 pub fn identify_to_vec<I>(&self, items: I) -> Vec<S>
80 where
81 I: IntoIterator,
82 I::Item: std::borrow::Borrow<T> + Send,
83 {
84 items
87 .into_iter()
88 .map(|item| (self.identifier)(item.borrow()).1)
90 .collect()
91 }
92
93 pub fn map_to_vec<U, F>(&self, f: F) -> Vec<U>
94 where
95 F: FnMut(&S) -> U,
96 {
97 self.selections.map_to_vec(f)
99 }
100
101 pub fn revalidate(&mut self) {
102 let mut set = self.selections.set.lock().unwrap();
103 let validator = &self.validator;
104
105 set.retain(|_, v| validator(v));
106 }
107
108 pub fn cycle_all_bg<I>(&self, items: I)
109 where
110 I: IntoIterator,
111 I::Item: std::borrow::Borrow<T> + Send,
112 {
113 let results: Vec<_> = items
114 .into_iter()
115 .map(|item| (self.identifier)(item.borrow()))
116 .collect();
117
118 let selections = self.selections.clone();
119
120 #[cfg(feature = "parallelism")]
121 tokio::task::spawn_blocking(move || {
122 let mut all = true;
123 let mut set_guard = selections.set.lock().unwrap();
124
125 let mut seen = 0;
126 for (i, (k, _v)) in results.iter().enumerate() {
127 if !set_guard.contains_key(k) {
128 all = false;
129 seen = i;
130 break;
131 }
132 }
133
134 if all {
135 for (k, _v) in results {
136 set_guard.swap_remove(&k); }
138 } else {
139 for (k, v) in results.into_iter().skip(seen) {
140 set_guard.insert(k, v);
141 }
142 }
143 });
144 #[cfg(not(feature = "parallelism"))]
145 {
146 let mut all = true;
147 let mut set_guard = selections.set.lock().unwrap();
148
149 let mut seen = 0;
150 for (i, (k, _v)) in results.iter().enumerate() {
151 if !set_guard.contains_key(k) {
152 all = false;
153 seen = i;
154 break;
155 }
156 }
157
158 if all {
159 for (k, _v) in results {
160 set_guard.swap_remove(&k); }
162 } else {
163 for (k, v) in results.into_iter().skip(seen) {
164 set_guard.insert(k, v);
165 }
166 };
167 };
168 }
169}
170
171#[derive(Debug, Clone)]
173struct SelectorImpl<K: Eq + Hash, S> {
174 pub set: Arc<Mutex<IndexMap<K, S, FxBuildHasher>>>,
175}
176
177impl<K: Eq + Hash, S> SelectorImpl<K, S>
178where
179 S: Selection,
180{
181 pub fn new() -> Self {
182 Self {
183 set: Arc::new(Mutex::new(IndexMap::with_hasher(FxBuildHasher))),
184 }
185 }
186
187 pub fn insert(&self, key: K, value: S) -> bool {
188 let mut set = self.set.lock().unwrap();
189 set.insert(key, value).is_none()
190 }
191
192 pub fn remove(&self, key: &K) -> bool {
193 let mut set = self.set.lock().unwrap();
194 set.shift_remove(key).is_some()
195 }
196
197 pub fn contains(&self, key: &K) -> bool {
198 let set = self.set.lock().unwrap();
199 set.contains_key(key)
200 }
201
202 pub fn clear(&self) {
203 let mut set = self.set.lock().unwrap();
204 set.clear();
205 }
206
207 pub fn clone(&self) -> Self {
208 Self {
209 set: Arc::clone(&self.set),
210 }
211 }
212
213 pub fn len(&self) -> usize {
214 let set = self.set.lock().unwrap();
215 set.len()
216 }
217
218 pub fn is_empty(&self) -> bool {
219 let set = self.set.lock().unwrap();
220 set.is_empty()
221 }
222
223 pub fn map_to_vec<U, F>(&self, f: F) -> Vec<U>
224 where
225 F: FnMut(&S) -> U,
226 {
227 let set = self.set.lock().unwrap();
228 set.values().map(f).collect()
229 }
230}