99 lines
4.4 KiB
Rust
99 lines
4.4 KiB
Rust
//! `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(())
|
|
}
|