use std::fs;
use std::path::{Path, PathBuf};
use crate::models::{Task, Todo};
use crate::traits::FilePersister;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Json {
path: PathBuf,
}
impl Json {
#[inline]
pub fn new<T: AsRef<Path>>(path: T) -> Self {
Self { path: path.as_ref().to_path_buf() }
}
#[inline]
pub fn array() -> String {
String::from("[]")
}
}
impl FilePersister for Json {
#[inline]
fn boxed(self) -> Box<dyn FilePersister> {
Box::new(self)
}
#[inline]
fn path(&self) -> &PathBuf {
&self.path
}
#[inline]
fn default(&self) -> String {
Self::array()
}
#[inline]
fn tasks(&self) -> super::Result<Vec<Task>> {
let content = fs::read_to_string(&self.path)?;
let tasks = serde_json::from_str(content.trim())?;
Ok(tasks)
}
#[inline]
fn open(&self) -> super::Result<fs::File> {
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(&self.path)?;
Ok(file)
}
#[inline]
fn write(&self, todo: &Todo) -> super::Result<()> {
serde_json::to_writer_pretty(self.open()?, &todo.tasks)?;
Ok(())
}
#[inline]
fn clean(&self) -> super::Result<()> {
fs::write(&self.path, self.default())?;
Ok(())
}
#[inline]
fn remove(&self) -> super::Result<()> {
fs::remove_file(&self.path)?;
Ok(())
}
}