use {
serde::{Deserialize, Serialize},
std::collections::BTreeMap,
};
use crate::on_disk::OnDisk;
const ARG_HISTORY_FILE: &str = ".arg_history.toml";
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ArgHistory {
pub entries: BTreeMap<String, String>,
}
impl ArgHistory {
fn make_key(command_id: &str, arg_name: &str) -> String {
format!("{command_id}/{arg_name}")
}
pub fn get(&self, command_id: &str, arg_name: &str) -> Option<&str> {
self.entries
.get(&Self::make_key(command_id, arg_name))
.map(|s| s.as_str())
}
pub fn set(&mut self, command_id: &str, arg_name: &str, value: &str) {
self.entries
.insert(Self::make_key(command_id, arg_name), value.to_string());
}
pub fn load(app_dir: &std::path::Path) -> OnDisk<Self> {
let path = app_dir.join(ARG_HISTORY_FILE);
OnDisk::<Self>::open_or_default(path.clone())
.unwrap_or_else(|_| OnDisk::new_from_default(path))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn get_set_roundtrip() {
let mut h = ArgHistory::default();
h.set("cmd1", "BRANCH", "main");
assert_eq!(h.get("cmd1", "BRANCH"), Some("main"));
}
#[test]
fn get_missing() {
let h = ArgHistory::default();
assert_eq!(h.get("cmd1", "BRANCH"), None);
}
#[test]
fn set_overwrites() {
let mut h = ArgHistory::default();
h.set("cmd1", "BRANCH", "main");
h.set("cmd1", "BRANCH", "develop");
assert_eq!(h.get("cmd1", "BRANCH"), Some("develop"));
}
#[test]
fn different_commands_different_keys() {
let mut h = ArgHistory::default();
h.set("cmd1", "BRANCH", "main");
h.set("cmd2", "BRANCH", "develop");
assert_eq!(h.get("cmd1", "BRANCH"), Some("main"));
assert_eq!(h.get("cmd2", "BRANCH"), Some("develop"));
}
}