//! `relicario settings {show, trash-retention, history-retention, attachment-cap, generator-defaults}`. use anyhow::Result; use crate::SettingsAction; pub fn cmd_settings(action: SettingsAction) -> Result<()> { use relicario_core::{ Capitalization, CharClasses, GeneratorRequest, HistoryRetention, SymbolCharset, TrashRetention, }; let vault = crate::session::UnlockedVault::unlock_interactive()?; let mut settings = vault.load_settings()?; match action { SettingsAction::Show => { println!("{}", serde_json::to_string_pretty(&settings)?); return Ok(()); } SettingsAction::TrashRetention { days, forever } => { settings.trash_retention = match (days, forever) { (Some(d), false) => TrashRetention::Days(d), (None, true) => TrashRetention::Forever, _ => anyhow::bail!("specify exactly one of --days or --forever"), }; } SettingsAction::HistoryRetention { last_n, days, forever } => { settings.field_history_retention = match (last_n, days, forever) { (Some(n), None, false) => HistoryRetention::LastN(n), (None, Some(d), false) => HistoryRetention::Days(d), (None, None, true) => HistoryRetention::Forever, _ => anyhow::bail!("specify exactly one of --last-n / --days / --forever"), }; } SettingsAction::AttachmentCap { per_attachment_max_bytes, per_item_max_count, per_vault_soft_cap_bytes, per_vault_hard_cap_bytes, } => { if let Some(v) = per_attachment_max_bytes { settings.attachment_caps.per_attachment_max_bytes = v; } if let Some(v) = per_item_max_count { settings.attachment_caps.per_item_max_count = v; } if let Some(v) = per_vault_soft_cap_bytes { settings.attachment_caps.per_vault_soft_cap_bytes = v; } if let Some(v) = per_vault_hard_cap_bytes { settings.attachment_caps.per_vault_hard_cap_bytes = v; } } SettingsAction::GeneratorDefaults { random, bip39, length, words, symbols, separator, } => { // Decide target mode: explicit flag wins, else preserve current. let target_bip39 = if random { false } else if bip39 { true } else { matches!(settings.generator_defaults, GeneratorRequest::Bip39 { .. }) }; // Pull existing fields where compatible, else seed with sensible // defaults (kept in sync with `GeneratorRequest::default()`). let (cur_length, cur_classes, cur_charset) = match &settings.generator_defaults { GeneratorRequest::Random { length, classes, symbol_charset } => { (*length, *classes, symbol_charset.clone()) } _ => ( 20, CharClasses { lower: true, upper: true, digits: true, symbols: true }, SymbolCharset::SafeOnly, ), }; let (cur_words, cur_sep, cur_cap) = match &settings.generator_defaults { GeneratorRequest::Bip39 { word_count, separator, capitalization } => { (*word_count, separator.clone(), *capitalization) } _ => (5, " ".to_string(), Capitalization::Lower), }; settings.generator_defaults = if target_bip39 { GeneratorRequest::Bip39 { word_count: words.unwrap_or(cur_words), separator: separator.unwrap_or(cur_sep), capitalization: cur_cap, } } else { let charset = match symbols.as_deref() { None => cur_charset, Some("safe") => SymbolCharset::SafeOnly, Some("extended") => SymbolCharset::Extended, Some(other) => SymbolCharset::Custom(other.to_string()), }; GeneratorRequest::Random { length: length.unwrap_or(cur_length), classes: cur_classes, symbol_charset: charset, } }; } } vault.save_settings(&settings)?; super::commit_paths(&vault, "settings: update", &["settings.enc"])?; eprintln!("Settings updated."); Ok(()) }