1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use std::cmp::Ordering;
use clashctl_interactive::{ProxySort, ProxySortBy, SortMethod, SortOrder, Sortable};
use crate::components::{ProxyGroup, ProxyItem, ProxyTree};
impl SortMethod<ProxyItem> for ProxySort {
fn sort_fn(&self, a: &ProxyItem, b: &ProxyItem) -> std::cmp::Ordering {
let cmp = match self.by() {
ProxySortBy::Name => a.name.cmp(&b.name),
ProxySortBy::Type => a.proxy_type.cmp(&b.proxy_type),
ProxySortBy::Delay => {
use Ordering::{Equal as Eq, Greater as Gt, Less as Lt};
match (a.delay(), b.delay()) {
(None, Some(_)) => Gt,
(Some(_), None) => Lt,
(Some(aa), Some(bb)) => {
if aa == 0 {
Gt
} else if bb == 0 {
Lt
} else {
aa.cmp(&bb)
}
}
(None, None) => Eq,
}
}
};
if matches!(self.order(), SortOrder::Descendant) {
cmp.reverse()
} else {
cmp
}
}
}
impl<'a> Sortable<'a, ProxySort> for ProxyGroup<'a> {
type Item<'b> = ProxyItem;
fn sort_with(&mut self, method: &ProxySort) {
let pointed = &self.members[self.cursor].name.clone();
let current = self.current.map(|x| self.members[x].name.clone());
self.members.sort_by(|a, b| method.sort_fn(a, b));
for (i, ProxyItem { name, .. }) in self.members.iter().enumerate() {
if name == pointed {
self.cursor = i;
}
if let Some(ref x) = current {
if name == x {
self.current = Some(i)
}
}
}
}
}
impl<'a> Sortable<'a, ProxySort> for ProxyTree<'a> {
type Item<'b> = ProxyItem;
fn sort_with(&mut self, method: &ProxySort) {
self.groups.iter_mut().for_each(|x| x.sort_with(method))
}
}