Skip to main content

recovery/
recovery.rs

1use app_json_settings::{ConfigError, ConfigManager};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Deserialize, Serialize, Default)]
5struct AppSettings {
6    theme: String,
7    launch_count: u32,
8}
9
10fn main() -> app_json_settings::Result<()> {
11    let root = std::env::temp_dir().join("app-json-settings-recovery-example");
12    let manager = ConfigManager::<AppSettings>::new()
13        .with_root_dir(&root)
14        .try_with_filename("settings.json")?;
15
16    // Simulate a settings file left unreadable by an external edit, so this
17    // example actually exercises the recovery branch below instead of
18    // silently taking the happy path. A real application would not do this;
19    // it would simply encounter an already-invalid file.
20    std::fs::create_dir_all(&root)?;
21    std::fs::write(manager.path(), "not-json")?;
22
23    let settings = match manager.load_or_default() {
24        Ok(settings) => settings,
25        Err(ConfigError::Deserialize(error)) => {
26            eprintln!("settings file is invalid, moving it aside: {error}");
27
28            // The backup carries the same sensitivity as the original
29            // settings file. Handle it with the same care you would give
30            // the original (see docs/src/save-behavior.md for the Unix
31            // permission model this crate applies to the file itself).
32            let backup = manager.path().with_extension("json.bak");
33            std::fs::rename(manager.path(), &backup)?;
34            println!("backed up invalid settings to: {}", backup.display());
35
36            manager.load_or_default()?
37        }
38        Err(error) => return Err(error),
39    };
40
41    println!("settings path: {}", manager.path().display());
42    println!("theme: {}", settings.theme);
43    println!("launch count: {}", settings.launch_count);
44
45    Ok(())
46}