First one-shot pass
This commit is contained in:
75
src/store/json_store.rs
Normal file
75
src/store/json_store.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use crate::store::schema::{KeyStatsData, LessonHistoryData, ProfileData};
|
||||
|
||||
pub struct JsonStore {
|
||||
base_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl JsonStore {
|
||||
pub fn new() -> Result<Self> {
|
||||
let base_dir = dirs::data_dir()
|
||||
.unwrap_or_else(|| PathBuf::from("."))
|
||||
.join("keydr");
|
||||
fs::create_dir_all(&base_dir)?;
|
||||
Ok(Self { base_dir })
|
||||
}
|
||||
|
||||
fn file_path(&self, name: &str) -> PathBuf {
|
||||
self.base_dir.join(name)
|
||||
}
|
||||
|
||||
fn load<T: DeserializeOwned + Default>(&self, name: &str) -> T {
|
||||
let path = self.file_path(name);
|
||||
if path.exists() {
|
||||
match fs::read_to_string(&path) {
|
||||
Ok(content) => serde_json::from_str(&content).unwrap_or_default(),
|
||||
Err(_) => T::default(),
|
||||
}
|
||||
} else {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn save<T: Serialize>(&self, name: &str, data: &T) -> Result<()> {
|
||||
let path = self.file_path(name);
|
||||
let tmp_path = path.with_extension("tmp");
|
||||
|
||||
let json = serde_json::to_string_pretty(data)?;
|
||||
let mut file = fs::File::create(&tmp_path)?;
|
||||
file.write_all(json.as_bytes())?;
|
||||
file.sync_all()?;
|
||||
|
||||
fs::rename(&tmp_path, &path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_profile(&self) -> ProfileData {
|
||||
self.load("profile.json")
|
||||
}
|
||||
|
||||
pub fn save_profile(&self, data: &ProfileData) -> Result<()> {
|
||||
self.save("profile.json", data)
|
||||
}
|
||||
|
||||
pub fn load_key_stats(&self) -> KeyStatsData {
|
||||
self.load("key_stats.json")
|
||||
}
|
||||
|
||||
pub fn save_key_stats(&self, data: &KeyStatsData) -> Result<()> {
|
||||
self.save("key_stats.json", data)
|
||||
}
|
||||
|
||||
pub fn load_lesson_history(&self) -> LessonHistoryData {
|
||||
self.load("lesson_history.json")
|
||||
}
|
||||
|
||||
pub fn save_lesson_history(&self, data: &LessonHistoryData) -> Result<()> {
|
||||
self.save("lesson_history.json", data)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user