fast_fs/models/
cls_file_list.rs1use crate::models::cls_file_entry::FileEntry;
8use crate::models::cls_sort_by::SortBy;
9use std::ops::{Deref, DerefMut};
10#[derive(Debug, Default)]
12pub struct FileList {
13 items: Vec<FileEntry>,
14 hidden: Vec<FileEntry>,
15 revision: u64,
17 version: u64,
19 sort_by: SortBy,
20 show_hidden: bool,
21}
22impl Deref for FileList {
23 type Target = Vec<FileEntry>;
24 fn deref(&self) -> &Self::Target {
25 &self.items
26 }
27}
28impl DerefMut for FileList {
29 fn deref_mut(&mut self) -> &mut Self::Target {
30 self.revision += 1;
31 &mut self.items
32 }
33}
34impl FileList {
35 pub fn new() -> Self {
37 Self::default()
38 }
39 pub fn from_entries(entries: Vec<FileEntry>) -> Self {
41 let mut list = Self::new();
42 list.update_full(entries);
43 list
44 }
45 pub fn update_full(&mut self, entries: Vec<FileEntry>) {
47 self.revision += 1;
48 if self.show_hidden {
49 self.items = entries;
50 self.hidden.clear();
51 } else {
52 let (hidden, visible): (Vec<_>, Vec<_>) =
53 entries.into_iter().partition(|e| e.is_hidden);
54 self.items = visible;
55 self.hidden = hidden;
56 }
57 }
58 pub fn push_batch(&mut self, entries: Vec<FileEntry>) {
60 self.revision += 1;
61 if self.show_hidden {
62 self.items.extend(entries);
63 } else {
64 for entry in entries {
65 if entry.is_hidden {
66 self.hidden.push(entry);
67 } else {
68 self.items.push(entry);
69 }
70 }
71 }
72 }
73 pub fn catchup(&mut self) -> bool {
75 if self.version == self.revision {
76 return false;
77 }
78 self.version = self.revision;
79 self.sort_items();
80 true
81 }
82 pub fn set_sort(&mut self, sort_by: SortBy) {
84 if self.sort_by != sort_by {
85 self.sort_by = sort_by;
86 self.revision += 1;
87 }
88 }
89 pub fn set_show_hidden(&mut self, show: bool) {
91 if self.show_hidden == show {
92 return;
93 }
94 self.show_hidden = show;
95 self.revision += 1;
96 if show {
97 self.items.append(&mut self.hidden);
98 } else {
99 let items = std::mem::take(&mut self.items);
100 let (hidden, visible): (Vec<_>, Vec<_>) = items.into_iter().partition(|e| e.is_hidden);
101 self.items = visible;
102 self.hidden = hidden;
103 }
104 }
105 pub fn revision(&self) -> u64 {
107 self.revision
108 }
109
110 pub fn needs_sort(&self) -> bool {
112 self.version != self.revision
113 }
114
115 pub fn sort_by(&self) -> SortBy {
117 self.sort_by
118 }
119
120 pub fn hidden_count(&self) -> usize {
122 self.hidden.len()
123 }
124 fn sort_items(&mut self) {
125 match self.sort_by {
126 SortBy::Name => {
127 self.items
128 .sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
129 }
130 SortBy::NameDesc => {
131 self.items
132 .sort_by(|a, b| b.name.to_lowercase().cmp(&a.name.to_lowercase()));
133 }
134 SortBy::Size => {
135 self.items.sort_by_key(|e| e.size);
136 }
137 SortBy::SizeDesc => {
138 self.items.sort_by(|a, b| b.size.cmp(&a.size));
139 }
140 SortBy::Modified => {
141 self.items.sort_by_key(|e| e.modified);
142 }
143 SortBy::ModifiedDesc => {
144 self.items.sort_by(|a, b| b.modified.cmp(&a.modified));
145 }
146 SortBy::Extension => {
147 self.items.sort_by(|a, b| {
148 let ext_cmp = a.extension().cmp(&b.extension());
149 if ext_cmp == std::cmp::Ordering::Equal {
150 a.name.to_lowercase().cmp(&b.name.to_lowercase())
151 } else {
152 ext_cmp
153 }
154 });
155 }
156 SortBy::DirsFirst => {
157 self.items.sort_by(|a, b| match (a.is_dir, b.is_dir) {
158 (true, false) => std::cmp::Ordering::Less,
159 (false, true) => std::cmp::Ordering::Greater,
160 _ => a.name.to_lowercase().cmp(&b.name.to_lowercase()),
161 });
162 }
163 }
164 }
165}
166
167