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 parse(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 #[allow(clippy::should_implement_trait)]
54 pub fn from_str(s: &str) -> Self {
55 Self::parse(s)
56 }
57
58 pub fn allows_recent_searches(self) -> bool {
60 !matches!(self, PrivacyMode::Strict)
61 }
62
63 pub fn allows_snippet_persistence(self) -> bool {
65 !matches!(self, PrivacyMode::Strict)
66 }
67
68 pub fn allows_diagnostics_sensitive_optins(self) -> bool {
70 !matches!(self, PrivacyMode::Strict)
71 }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct PrivacySettings {
83 pub mode: PrivacyMode,
84 pub remember_recent_searches: bool,
86 pub persist_snippets: bool,
88 pub clear_temporary_previews_on_exit: bool,
90 pub diagnostics_include_paths: bool,
92 pub diagnostics_include_recent_searches: bool,
94}
95
96impl Default for PrivacySettings {
97 fn default() -> Self {
98 Self {
99 mode: PrivacyMode::Standard,
100 remember_recent_searches: true,
101 persist_snippets: true,
102 clear_temporary_previews_on_exit: false,
103 diagnostics_include_paths: false,
104 diagnostics_include_recent_searches: false,
105 }
106 }
107}
108
109impl PrivacySettings {
110 pub fn with_mode_applied(mut self) -> Self {
115 if self.mode == PrivacyMode::Strict {
116 self.remember_recent_searches = false;
117 self.persist_snippets = false;
118 self.diagnostics_include_paths = false;
119 self.diagnostics_include_recent_searches = false;
120 }
121 self
122 }
123
124 pub fn effective_recent_searches(&self) -> bool {
126 self.mode.allows_recent_searches() && self.remember_recent_searches
127 }
128
129 pub fn effective_snippet_persistence(&self) -> bool {
131 self.mode.allows_snippet_persistence() && self.persist_snippets
132 }
133}
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub enum LocalDataCategory {
144 SourcePaths,
145 FileMetadata,
146 ExtractedText,
147 KeywordIndex,
148 Embeddings,
149 Snippets,
150 TemporaryPreviews,
151 RecentSearches,
152 Logs,
153 Diagnostics,
154 ModelFiles,
155 Settings,
156}
157
158impl LocalDataCategory {
159 pub fn user_label(self) -> &'static str {
161 match self {
162 LocalDataCategory::SourcePaths => "Folder list",
163 LocalDataCategory::FileMetadata => "File information",
164 LocalDataCategory::ExtractedText => "Prepared text",
165 LocalDataCategory::KeywordIndex => "Search data",
166 LocalDataCategory::Embeddings => "Better search data",
167 LocalDataCategory::Snippets => "Temporary previews",
168 LocalDataCategory::TemporaryPreviews => "Temporary previews",
169 LocalDataCategory::RecentSearches => "Recent searches",
170 LocalDataCategory::Logs => "Logs",
171 LocalDataCategory::Diagnostics => "Support files",
172 LocalDataCategory::ModelFiles => "Search helper",
173 LocalDataCategory::Settings => "App settings",
174 }
175 }
176}
177
178#[derive(Debug, Clone)]
185pub struct DiagnosticsPolicy {
186 pub include_raw_paths: bool,
187 pub include_folder_names: bool,
188 pub include_recent_searches: bool,
189 pub include_detailed_logs: bool,
190 pub privacy_mode: PrivacyMode,
191}
192
193impl Default for DiagnosticsPolicy {
194 fn default() -> Self {
195 Self {
196 include_raw_paths: false,
197 include_folder_names: false,
198 include_recent_searches: false,
199 include_detailed_logs: false,
200 privacy_mode: PrivacyMode::Standard,
201 }
202 }
203}
204
205impl DiagnosticsPolicy {
206 pub fn from_privacy(settings: &PrivacySettings) -> Self {
208 let strict = settings.mode == PrivacyMode::Strict;
209 Self {
210 include_raw_paths: false, include_folder_names: false, include_recent_searches: if strict {
213 false
214 } else {
215 settings.diagnostics_include_recent_searches
216 },
217 include_detailed_logs: false,
218 privacy_mode: settings.mode,
219 }
220 }
221
222 pub fn allows_sensitive_optins(&self) -> bool {
224 self.privacy_mode.allows_diagnostics_sensitive_optins()
225 }
226}