gui_server_api/navigation/
filepicker.rs1#[derive(Debug, Copy, Clone, Eq, PartialEq, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
7pub enum Location {
8 Internal,
9 Airlock,
10 External,
11}
12
13#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
14pub enum AllowedLocations {
15 All,
16 Specific(Vec<Location>),
17}
18
19impl AllowedLocations {
20 pub fn specific<T: IntoIterator<Item = Location>>(locations: T) -> Self {
21 Self::Specific(locations.into_iter().collect::<Vec<_>>())
22 }
23
24 pub fn contains(&self, location: Location) -> bool {
25 match self {
26 Self::All => true,
27 Self::Specific(locations) => locations.contains(&location),
28 }
29 }
30
31 pub fn len(&self) -> Option<usize> {
32 match self {
33 Self::All => None,
34 Self::Specific(locations) => Some(locations.len()),
35 }
36 }
37
38 pub fn is_empty(&self) -> bool { self.len().map(|len| len == 0).unwrap_or(false) }
39}
40
41#[derive(Debug, Clone, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
42pub enum AllowedExtensions {
43 All,
44 Specific(Vec<String>),
45}
46
47impl AllowedExtensions {
48 pub fn specific<S: AsRef<str>, T: IntoIterator<Item = S>>(extensions: T) -> Self {
49 Self::Specific(extensions.into_iter().map(|s| s.as_ref().to_string()).collect::<Vec<_>>())
50 }
51
52 pub fn contains<S: AsRef<str>>(&self, extension: S) -> bool {
53 match self {
54 Self::All => true,
55 Self::Specific(extensions) => extensions.contains(&extension.as_ref().to_string()),
56 }
57 }
58}
59
60#[derive(Debug, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
72pub struct SelectFileOptions {
73 start_location: Location,
74 locations: AllowedLocations,
75 extensions: AllowedExtensions,
76 hidden_allowed: bool,
77 dirs_allowed: bool,
78 search_allowed: bool,
79 dir_selection_mode: bool,
80 multiple_selection_mode: bool,
81}
82
83impl Default for SelectFileOptions {
84 fn default() -> Self {
85 Self {
86 start_location: Location::Internal,
87 locations: AllowedLocations::All,
88 extensions: AllowedExtensions::All,
89 hidden_allowed: true,
90 search_allowed: true,
91 dirs_allowed: true,
92 dir_selection_mode: false,
93 multiple_selection_mode: false,
94 }
95 }
96}
97
98impl SelectFileOptions {
99 pub fn with_dir_selection_mode(self, dir_selection_mode: bool) -> Self {
104 Self { dir_selection_mode, dirs_allowed: self.dirs_allowed || dir_selection_mode, ..self }
105 }
106
107 pub fn with_dirs_allowed(self, allow_directories: bool) -> Self {
111 Self { dirs_allowed: allow_directories || self.dir_selection_mode, ..self }
112 }
113
114 pub fn with_search_allowed(self, allow_search: bool) -> Self {
116 Self { search_allowed: allow_search, ..self }
117 }
118
119 pub fn with_multiple_selection_mode(self, multiple_selection_mode: bool) -> Self {
123 let dir_selection_mode = self.dir_selection_mode && !multiple_selection_mode;
124 Self { multiple_selection_mode, dir_selection_mode, ..self }
125 }
126
127 pub fn with_hidden_allowed(self, hidden_allowed: bool) -> Self { Self { hidden_allowed, ..self } }
129
130 pub fn with_start_location(self, start_location: Location) -> Self { Self { start_location, ..self } }
131
132 pub fn with_allowed_locations(self, locations: AllowedLocations) -> Self { Self { locations, ..self } }
133
134 pub fn with_allowed_extensions(self, extensions: AllowedExtensions) -> Self {
135 Self { extensions, ..self }
136 }
137
138 pub fn search_allowed(&self) -> bool { self.search_allowed }
139
140 pub fn dirs_allowed(&self) -> bool { self.dirs_allowed }
141
142 pub fn hidden_allowed(&self) -> bool { self.hidden_allowed }
143
144 pub fn dir_selection_mode(&self) -> bool { self.dir_selection_mode }
145
146 pub fn multiple_selection_mode(&self) -> bool { self.multiple_selection_mode }
147
148 pub fn start_location(&self) -> Location { self.start_location }
149
150 pub fn allowed_locations(&self) -> &AllowedLocations { &self.locations }
151
152 pub fn allowed_extensions(&self) -> &AllowedExtensions { &self.extensions }
153
154 pub fn from_slice(data: &[u8]) -> Option<Self> {
155 let Ok(archived) = rkyv::access::<ArchivedSelectFileOptions, rkyv::rancor::Error>(data) else {
156 return None;
157 };
158 rkyv::deserialize::<Self, rkyv::rancor::Error>(archived).ok()
159 }
160
161 pub fn serialize(&self) -> Vec<u8> { rkyv::to_bytes::<rkyv::rancor::Error>(self).unwrap().to_vec() }
162}
163
164#[derive(Debug, rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
165pub struct SelectFileResult {
166 pub files: Vec<(String, Location)>,
167}
168
169impl SelectFileResult {
170 pub fn new(files: Vec<(String, Location)>) -> Self { Self { files } }
171
172 pub fn files(&self) -> &[(String, Location)] { &self.files }
173
174 pub fn from_slice(data: &[u8]) -> Option<Self> {
175 let Ok(archived) = rkyv::access::<ArchivedSelectFileResult, rkyv::rancor::Error>(data) else {
176 return None;
177 };
178 rkyv::deserialize::<Self, rkyv::rancor::Error>(archived).ok()
179 }
180
181 pub fn serialize(&self) -> Vec<u8> { rkyv::to_bytes::<rkyv::rancor::Error>(self).unwrap().to_vec() }
182}