Skip to main content

max / goingson

Apply rustfmt across the crate Formatting only, no behavior change. cargo check --all-targets passes.
Co-Authored-By
Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-21 23:46 UTC
Signed with PGP, not checked
Commit: 83b6eb65b6479af28148d1b8ae86ee4574b62938
Parent: 189683c
187 files changed, +11805 insertions, -5752 deletions
@@ -3,7 +3,7 @@
3 3 //! Runs in the background and creates compressed backups based on user settings.
4 4 //! Handles backup retention by pruning old backups when max count is exceeded.
5 5
6 - use crate::export::backup::{write_backup, FullExport};
6 + use crate::export::backup::{FullExport, write_backup};
7 7 use crate::state::{AppState, DESKTOP_USER_ID};
8 8 use chrono::Utc;
9 9 use std::sync::Arc;
@@ -164,7 +164,9 @@
164 164 let filename = backup_filename(now);
165 165 let file_path = backup_dir.join(&filename);
166 166
167 - let export = collect_full_export(state, DESKTOP_USER_ID).await.map_err(|e| e.to_string())?;
167 + let export = collect_full_export(state, DESKTOP_USER_ID)
168 + .await
169 + .map_err(|e| e.to_string())?;
168 170 let item_count = export.total_count();
169 171 let max_to_keep = settings.max_backups_to_keep as usize;
170 172
@@ -259,7 +261,9 @@
259 261 let filename = backup_filename(now);
260 262 let file_path = backup_dir.join(&filename);
261 263
262 - let export = collect_full_export(state, DESKTOP_USER_ID).await.map_err(|e| e.to_string())?;
264 + let export = collect_full_export(state, DESKTOP_USER_ID)
265 + .await
266 + .map_err(|e| e.to_string())?;
263 267 let item_count = export.total_count();
264 268
265 269 // Directory creation + gzip serialization are blocking and take seconds on a
@@ -318,7 +322,8 @@
318 322 let path = dir.join(format!("goingson-backup-{i:03}.json.gz"));
319 323 std::fs::write(&path, [i as u8]).unwrap();
320 324 let f = std::fs::File::options().write(true).open(&path).unwrap();
321 - f.set_modified(base + Duration::from_secs(i as u64)).unwrap();
325 + f.set_modified(base + Duration::from_secs(i as u64))
326 + .unwrap();
322 327 }
323 328 }
324 329
@@ -357,6 +362,10 @@
357 362 let dir = tempfile::tempdir().unwrap();
358 363 seed_backups(dir.path(), 9);
359 364 prune_old_backups(dir.path(), 5).unwrap();
360 - assert_eq!(gz_count(dir.path()), 5, "a limit above the floor is honored");
365 + assert_eq!(
366 + gz_count(dir.path()),
367 + 5,
368 + "a limit above the floor is honored"
369 + );
361 370 }
362 371 }
@@ -6,8 +6,8 @@
6 6 use notify::RecursiveMode;
7 7 use notify_debouncer_mini::new_debouncer;
8 8 use std::path::Path;
9 - use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
10 9 use std::sync::Arc;
10 + use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
11 11 use std::time::Duration;
12 12 use tauri::{Emitter, Manager};
13 13 use tracing::{debug, error, info, warn};
@@ -36,7 +36,10 @@
36 36 let db_path = app_data_dir.join("goingson.db");
37 37
38 38 if !db_path.exists() {
39 - warn!(?db_path, "Database file does not exist yet, watcher will start when it's created");
39 + warn!(
40 + ?db_path,
41 + "Database file does not exist yet, watcher will start when it's created"
42 + );
40 43 }
41 44
42 45 info!(?db_path, "Starting database file watcher");
@@ -96,7 +99,10 @@
96 99 };
97 100
98 101 // Watch the app data directory (contains db, wal, shm files)
99 - if let Err(e) = debouncer.watcher().watch(&app_data_dir, RecursiveMode::NonRecursive) {
102 + if let Err(e) = debouncer
103 + .watcher()
104 + .watch(&app_data_dir, RecursiveMode::NonRecursive)
105 + {
100 106 error!(?app_data_dir, "Failed to watch directory: {}", e);
101 107 return;
102 108 }
@@ -113,9 +119,7 @@
113 119 match rx.recv_timeout(Duration::from_secs(1)) {
114 120 Ok(Ok(events)) => {
115 121 // Check if any event is for our database files
116 - let db_changed = events.iter().any(|event| {
117 - is_db_file(&event.path, &db_path)
118 - });
122 + let db_changed = events.iter().any(|event| is_db_file(&event.path, &db_path));
119 123
120 124 if db_changed {
121 125 // Check if enough time has passed since last event
@@ -163,7 +167,10 @@
163 167
164 168 /// Check if a path is one of the SQLite database files
165 169 fn is_db_file(path: &Path, db_path: &Path) -> bool {
166 - let db_name = db_path.file_name().and_then(|n| n.to_str()).unwrap_or("goingson.db");
170 + let db_name = db_path
171 + .file_name()
172 + .and_then(|n| n.to_str())
173 + .unwrap_or("goingson.db");
167 174
168 175 if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) {
169 176 // Match main db file and WAL/SHM/journal files
@@ -6,7 +6,7 @@
6 6 use std::collections::HashMap;
7 7 use std::sync::Arc;
8 8 use tauri::Manager;
9 - use tokio::time::{interval, Duration};
9 + use tokio::time::{Duration, interval};
10 10 use tokio_util::sync::CancellationToken;
11 11 use tracing::{debug, error, info, warn};
12 12
@@ -36,7 +36,10 @@
36 36 // Track consecutive failures per account for exponential backoff
37 37 let mut failure_counts: HashMap<String, u32> = HashMap::new();
38 38
39 - info!("Email sync scheduler started (checking every {} seconds)", CHECK_INTERVAL_SECS);
39 + info!(
40 + "Email sync scheduler started (checking every {} seconds)",
41 + CHECK_INTERVAL_SECS
42 + );
40 43
41 44 // Infinite tick loop: sleep for CHECK_INTERVAL_SECS, then check all accounts.
42 45 // The first tick fires immediately (tokio::time::interval behavior).
@@ -85,7 +88,10 @@
85 88 return Ok(());
86 89 }
87 90
88 - debug!("Email sync scheduler: {} account(s) need sync", accounts.len());
91 + debug!(
92 + "Email sync scheduler: {} account(s) need sync",
93 + accounts.len()
94 + );
89 95
90 96 // A failing account never updates last_sync_at, so it stays "due" and remains
91 97 // in this list every tick; any failure_counts key absent here belongs to an
@@ -102,7 +108,9 @@
102 108 // Exponential backoff: skip this tick if the account has been failing
103 109 let consecutive_failures = failure_counts.get(&account_key).copied().unwrap_or(0);
104 110 if consecutive_failures > 0 {
105 - let backoff = 2u32.pow(consecutive_failures.min(4)).min(MAX_BACKOFF_MULTIPLIER);
111 + let backoff = 2u32
112 + .pow(consecutive_failures.min(4))
113 + .min(MAX_BACKOFF_MULTIPLIER);
106 114 // Use a simple modulo check: only attempt every `backoff` ticks
107 115 // This is approximate but avoids needing per-account timestamps
108 116 if rand_skip(backoff) {
@@ -138,7 +146,10 @@
138 146 let body = if result.emails_saved == 1 {
139 147 format!("1 new email in {}", account.account_name)
140 148 } else {
141 - format!("{} new emails in {}", result.emails_saved, account.account_name)
149 + format!(
150 + "{} new emails in {}",
151 + result.emails_saved, account.account_name
152 + )
142 153 };
143 154 send_notification(app, "New Mail", &body);
144 155 }