1use mxr_core::{SearchMode as CoreSearchMode, SemanticProfile};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::path::PathBuf;
5
6#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
7#[serde(rename_all = "snake_case")]
8pub enum GmailCredentialSource {
9 #[default]
10 Bundled,
11 Custom,
12}
13
14#[derive(Debug, Clone, Default, Serialize, Deserialize)]
16#[serde(default)]
17pub struct MxrConfig {
18 pub general: GeneralConfig,
19 pub accounts: HashMap<String, AccountConfig>,
20 pub render: RenderConfig,
21 pub search: SearchConfig,
22 pub snooze: SnoozeConfig,
23 pub logging: LoggingConfig,
24 pub appearance: AppearanceConfig,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(default)]
30pub struct GeneralConfig {
31 pub editor: Option<String>,
32 pub default_account: Option<String>,
33 pub sync_interval: u64,
34 pub hook_timeout: u64,
35 pub attachment_dir: PathBuf,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct AccountConfig {
41 pub name: String,
42 pub email: String,
43 pub sync: Option<SyncProviderConfig>,
44 pub send: Option<SendProviderConfig>,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49#[serde(tag = "type", rename_all = "snake_case")]
50pub enum SyncProviderConfig {
51 Gmail {
52 #[serde(default)]
53 credential_source: GmailCredentialSource,
54 client_id: String,
55 client_secret: Option<String>,
56 token_ref: String,
57 },
58 Imap {
59 host: String,
60 port: u16,
61 username: String,
62 password_ref: String,
63 use_tls: bool,
64 },
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(tag = "type", rename_all = "snake_case")]
70pub enum SendProviderConfig {
71 Gmail,
72 Smtp {
73 host: String,
74 port: u16,
75 username: String,
76 password_ref: String,
77 use_tls: bool,
78 },
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(default)]
84pub struct RenderConfig {
85 pub html_command: Option<String>,
86 pub reader_mode: bool,
87 pub show_reader_stats: bool,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(default)]
93pub struct SearchConfig {
94 pub default_sort: SortOrder,
95 pub max_results: usize,
96 pub default_mode: CoreSearchMode,
97 pub semantic: SemanticConfig,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
102#[serde(rename_all = "snake_case")]
103pub enum SortOrder {
104 DateDesc,
105 DateAsc,
106 Relevance,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(default)]
112pub struct SemanticConfig {
113 pub enabled: bool,
114 pub auto_download_models: bool,
115 pub active_profile: SemanticProfile,
116 pub max_pending_jobs: usize,
117 pub query_timeout_ms: u64,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122#[serde(default)]
123pub struct SnoozeConfig {
124 pub morning_hour: u8,
125 pub evening_hour: u8,
126 pub weekend_day: String,
127 pub weekend_hour: u8,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132#[serde(default)]
133pub struct LoggingConfig {
134 pub level: String,
135 pub max_size_mb: u32,
136 pub max_files: u32,
137 pub stderr: bool,
138 pub event_retention_days: u32,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
143#[serde(default)]
144pub struct AppearanceConfig {
145 pub theme: String,
146 pub sidebar: bool,
147 pub date_format: String,
148 pub date_format_full: String,
149 pub subject_max_width: usize,
150}