1use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
20#[serde(rename_all = "snake_case")]
21pub enum PrivacyMode {
22 #[default]
24 Standard,
25 Strict,
27 Portable,
29 Diagnostics,
31}
32
33impl PrivacyMode {
34 pub fn as_str(self) -> &'static str {
36 match self {
37 PrivacyMode::Standard => "standard",
38 PrivacyMode::Strict => "strict",
39 PrivacyMode::Portable => "portable",
40 PrivacyMode::Diagnostics => "diagnostics",
41 }
42 }
43
44 pub fn from_str(s: &str) -> Self {
45 match s {
46 "strict" => PrivacyMode::Strict,
47 "portable" => PrivacyMode::Portable,
48 "diagnostics" => PrivacyMode::Diagnostics,
49 _ => PrivacyMode::Standard,
50 }
51 }
52
53 pub fn allows_recent_searches(self) -> bool {
55 !matches!(self, PrivacyMode::Strict)
56 }
57
58 pub fn allows_snippet_persistence(self) -> bool {
60 !matches!(self, PrivacyMode::Strict)
61 }
62
63 pub fn allows_diagnostics_sensitive_optins(self) -> bool {
65 !matches!(self, PrivacyMode::Strict)
66 }
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct PrivacySettings {
78 pub mode: PrivacyMode,
79 pub remember_recent_searches: bool,
81 pub persist_snippets: bool,
83 pub clear_temporary_previews_on_exit: bool,
85 pub diagnostics_include_paths: bool,
87 pub diagnostics_include_recent_searches: bool,
89}
90
91impl Default for PrivacySettings {
92 fn default() -> Self {
93 Self {
94 mode: PrivacyMode::Standard,
95 remember_recent_searches: true,
96 persist_snippets: true,
97 clear_temporary_previews_on_exit: false,
98 diagnostics_include_paths: false,
99 diagnostics_include_recent_searches: false,
100 }
101 }
102}
103
104impl PrivacySettings {
105 pub fn with_mode_applied(mut self) -> Self {
110 if self.mode == PrivacyMode::Strict {
111 self.remember_recent_searches = false;
112 self.persist_snippets = false;
113 self.diagnostics_include_paths = false;
114 self.diagnostics_include_recent_searches = false;
115 }
116 self
117 }
118
119 pub fn effective_recent_searches(&self) -> bool {
121 self.mode.allows_recent_searches() && self.remember_recent_searches
122 }
123
124 pub fn effective_snippet_persistence(&self) -> bool {
126 self.mode.allows_snippet_persistence() && self.persist_snippets
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq)]
138pub enum LocalDataCategory {
139 SourcePaths,
140 FileMetadata,
141 ExtractedText,
142 KeywordIndex,
143 Embeddings,
144 Snippets,
145 TemporaryPreviews,
146 RecentSearches,
147 Logs,
148 Diagnostics,
149 ModelFiles,
150 Settings,
151}
152
153impl LocalDataCategory {
154 pub fn user_label(self) -> &'static str {
156 match self {
157 LocalDataCategory::SourcePaths => "Folder list",
158 LocalDataCategory::FileMetadata => "File information",
159 LocalDataCategory::ExtractedText => "Prepared text",
160 LocalDataCategory::KeywordIndex => "Search data",
161 LocalDataCategory::Embeddings => "Better search data",
162 LocalDataCategory::Snippets => "Temporary previews",
163 LocalDataCategory::TemporaryPreviews => "Temporary previews",
164 LocalDataCategory::RecentSearches => "Recent searches",
165 LocalDataCategory::Logs => "Logs",
166 LocalDataCategory::Diagnostics => "Support files",
167 LocalDataCategory::ModelFiles => "Search helper",
168 LocalDataCategory::Settings => "App settings",
169 }
170 }
171}
172
173#[derive(Debug, Clone)]
180pub struct DiagnosticsPolicy {
181 pub include_raw_paths: bool,
182 pub include_folder_names: bool,
183 pub include_recent_searches: bool,
184 pub include_detailed_logs: bool,
185 pub privacy_mode: PrivacyMode,
186}
187
188impl Default for DiagnosticsPolicy {
189 fn default() -> Self {
190 Self {
191 include_raw_paths: false,
192 include_folder_names: false,
193 include_recent_searches: false,
194 include_detailed_logs: false,
195 privacy_mode: PrivacyMode::Standard,
196 }
197 }
198}
199
200impl DiagnosticsPolicy {
201 pub fn from_privacy(settings: &PrivacySettings) -> Self {
203 let strict = settings.mode == PrivacyMode::Strict;
204 Self {
205 include_raw_paths: false, include_folder_names: if strict { false } else { false }, include_recent_searches: if strict {
208 false
209 } else {
210 settings.diagnostics_include_recent_searches
211 },
212 include_detailed_logs: false,
213 privacy_mode: settings.mode,
214 }
215 }
216
217 pub fn allows_sensitive_optins(&self) -> bool {
219 self.privacy_mode.allows_diagnostics_sensitive_optins()
220 }
221}