68 lines
1.6 KiB
Rust
68 lines
1.6 KiB
Rust
use std::{fs::{create_dir_all, read_to_string}, path::{Path, PathBuf}};
|
|
use chrono::{DateTime, FixedOffset};
|
|
use serde::{Serialize, Deserialize};
|
|
use tera::escape_html;
|
|
use std::str::FromStr;
|
|
use std::io::Result as IoRes;
|
|
|
|
const JOURNAL_PATH: &str = "./journals";
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
pub struct Line {
|
|
pub line: String,
|
|
pub uploaded_date: DateTime<FixedOffset>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
pub struct Journal {
|
|
pub id: String,
|
|
pub edit_key: String,
|
|
pub lines: Vec<Line>,
|
|
}
|
|
|
|
impl Journal {
|
|
pub fn new(id: String, edit_key: String) -> Self {
|
|
Self {
|
|
id,
|
|
edit_key,
|
|
lines: Vec::new(),
|
|
}
|
|
}
|
|
pub fn load_or_create(id: String, key: String) -> Self {
|
|
match Self::load(&id) {
|
|
Some(journal) => journal,
|
|
None => Self::new(id, key),
|
|
}
|
|
}
|
|
|
|
pub fn load(id: &str) -> Option<Self> {
|
|
ensure_journal_path_exists().unwrap();
|
|
let journal_path = get_journal_path(&id);
|
|
|
|
match read_to_string(&journal_path) {
|
|
Ok(v) => Some(serde_json::from_str(&v).unwrap()),
|
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => None,
|
|
Err(_e) => unimplemented!()
|
|
}
|
|
|
|
}
|
|
|
|
pub fn save(&self) -> IoRes<()> {
|
|
ensure_journal_path_exists().unwrap();
|
|
let journal_path = get_journal_path(&self.id);
|
|
let data = serde_json::to_string(self).unwrap();
|
|
|
|
std::fs::write(journal_path, data)
|
|
}
|
|
}
|
|
|
|
fn get_journal_path(id: &str) -> PathBuf {
|
|
let file = escape_html(id);
|
|
PathBuf::from_str(JOURNAL_PATH).unwrap().join(Path::new(&file))
|
|
}
|
|
|
|
fn ensure_journal_path_exists() -> IoRes<()> {
|
|
create_dir_all(Path::new(JOURNAL_PATH))
|
|
}
|
|
|