use std::collections::HashMap; use std::fs; use std::fs::OpenOptions; use std::io::Write; use std::path::Path; use serde_derive::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug)] pub(crate) struct SeriesHistory { pub(crate) series: HashMap<String, PostHistory>, } impl SeriesHistory { pub(crate) fn load_history() -> Result<Self, String> { match Path::new("history.toml").exists() { true => { let file_contents: String = match fs::read_to_string("history.toml") { Ok(data) => data, Err(e) => return Err(format!("{}", e)), }; let history: Result<SeriesHistory, toml::de::Error> = match file_contents.len() { 0 => return Ok(SeriesHistory { series: HashMap::new(), }), _ => toml::from_str(file_contents.as_str()), }; match history { Ok(data) => Ok(data), Err(e) => Err(format!("{}", e)) } }, false => { Ok(SeriesHistory { series: HashMap::new(), }) } } } pub(crate) fn save_history(&self) -> std::io::Result<usize> { let mut file = OpenOptions::new() .read(true) .write(true) .create(true) .open("history.toml") .unwrap(); let json_data = toml::to_string_pretty(&self).unwrap(); file.write(json_data.as_bytes()) } pub(crate) fn check_for_post(&self, series: &str, part: &str, title: &str) -> bool { if let Some(series_map) = self.series.get(series) { if let Some(part_info) = series_map.parts.get(part) { return part_info.volume == title || part_info.chapter == title } } false } pub(crate) fn get_series(&self, series: &str) -> PostHistory { match self.series.get(series) { Some(history) => history.clone(), None => PostHistory { parts: HashMap::new() } } } pub(crate) fn set_series(&mut self, series: &str, data: PostHistory) { self.series.entry(series.to_string()).and_modify(|val| { *val = data.clone() }) .or_insert(data); } } #[derive(Serialize, Deserialize, Clone, Debug)] pub(crate) struct PostHistory { pub(crate) parts: HashMap<String, PostHistoryInner>, } impl PostHistory { pub(crate) fn get_part(&self, part: &str) -> PostHistoryInner { match self.parts.get(part) { Some(history) => history.clone(), None => PostHistoryInner { volume: "".to_string(), chapter: "".to_string(), } } } pub(crate) fn set_part(&mut self, part: &str, data: PostHistoryInner) { self.parts.entry(part.to_string()).and_modify(|val| { *val = data.clone() }) .or_insert(data); } } #[derive(Serialize, Deserialize, Clone, Debug)] pub(crate) struct PostHistoryInner { pub(crate) volume: String, pub(crate) chapter: String, }