use crate::domain::journal::Journal;
use crate::persistence::journal_record::JournalRecord;
use crate::repositories::repository::Repository;
use crate::store::store;
use anyhow::Result;
use std::{
collections::HashMap,
fs,
path::{Path, PathBuf},
};
use uuid::Uuid;
pub struct JournalRepository {
store_path: PathBuf,
}
impl JournalRepository {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
Self {
store_path: path.as_ref().to_path_buf(),
}
}
fn ensure_store_dir(&self) -> std::io::Result<()> {
if let Some(parent) = self.store_path.parent() {
fs::create_dir_all(parent)?;
}
Ok(())
}
}
impl Repository<Journal> for JournalRepository {
fn add(&self, journal: &Journal) -> Result<()> {
let mut journals: HashMap<Uuid, JournalRecord> = if self.store_path.exists() {
store::read_json(&self.store_path)?
} else {
HashMap::new()
};
journals.insert(journal.id, journal.into());
self.ensure_store_dir()?;
store::save_json(&self.store_path, &journals)?;
Ok(())
}
fn get(&self, id: &Uuid) -> Result<Option<Journal>> {
if !self.store_path.exists() {
return Ok(None);
}
let journals: HashMap<Uuid, JournalRecord> = store::read_json(&self.store_path)?;
Ok(journals.get(id).map(|journal| journal.into()))
}
fn get_by_name(&self, name: &String) -> Result<Option<Journal>> {
if !self.store_path.exists() {
return Ok(None);
}
let journals: HashMap<Uuid, JournalRecord> = store::read_json(&self.store_path)?;
let journals_by_name_map: HashMap<String, JournalRecord> = journals
.into_iter()
.map(|(_, journal)| (journal.name.clone(), journal))
.collect();
Ok(journals_by_name_map.get(name).map(|journal| journal.into()))
}
fn update(&self, journal: &Journal) -> Result<()> {
let mut journals: HashMap<Uuid, JournalRecord> = if self.store_path.exists() {
store::read_json(&self.store_path)?
} else {
HashMap::new()
};
journals.insert(journal.id, journal.into());
self.ensure_store_dir()?;
store::save_json(&self.store_path, &journals)?;
Ok(())
}
}