use std::path::PathBuf;
const KEY_THEME: &[u8] = b"tui_theme";
pub struct TuiStorage {
db: Option<sled::Db>,
}
impl TuiStorage {
pub fn open() -> Self {
let db = Self::db_path().and_then(|path| sled::open(path).ok());
Self { db }
}
pub fn save_theme(&self, name: &str) {
if let Some(db) = &self.db {
let _ = db.insert(KEY_THEME, name.as_bytes());
let _ = db.flush();
}
}
pub fn load_theme(&self) -> Option<String> {
let db = self.db.as_ref()?;
let bytes = db.get(KEY_THEME).ok()??;
String::from_utf8(bytes.to_vec()).ok()
}
fn db_path() -> Option<PathBuf> {
let mut path = dirs::config_dir()?;
path.push("flashkraft");
std::fs::create_dir_all(&path).ok()?;
path.push("tui-prefs.db");
Some(path)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn temp_storage() -> TuiStorage {
let tmp = tempfile::tempdir().unwrap();
let db = sled::open(tmp.path().join("test.db")).ok();
TuiStorage { db }
}
#[test]
fn load_theme_returns_none_when_empty() {
let s = temp_storage();
assert!(s.load_theme().is_none());
}
#[test]
fn save_and_load_theme_roundtrip() {
let s = temp_storage();
s.save_theme("Tokyo Night");
assert_eq!(s.load_theme().as_deref(), Some("Tokyo Night"));
}
#[test]
fn save_theme_overwrites_previous() {
let s = temp_storage();
s.save_theme("Dracula");
s.save_theme("Nord");
assert_eq!(s.load_theme().as_deref(), Some("Nord"));
}
#[test]
fn load_theme_with_no_db_returns_none() {
let s = TuiStorage { db: None };
assert!(s.load_theme().is_none());
}
#[test]
fn save_theme_with_no_db_is_noop() {
let s = TuiStorage { db: None };
s.save_theme("Catppuccin Mocha"); }
#[test]
fn roundtrip_all_preset_names() {
use tui_file_explorer::Theme;
let s = temp_storage();
for (name, _, _) in Theme::all_presets() {
s.save_theme(name);
assert_eq!(
s.load_theme().as_deref(),
Some(name),
"roundtrip failed for preset '{name}'"
);
}
}
}