use std::{
fs::File,
ops::{Deref, DerefMut},
path::PathBuf,
};
use crate::{Result, utils::novel_catch_dir};
use parse_book_source::BookSource;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct BookSourceCache {
pub book_sources: Vec<BookSource>,
}
impl BookSourceCache {
pub fn get_cache_file_path() -> Result<PathBuf> {
Ok(PathBuf::new()
.join(novel_catch_dir()?)
.join("book_sources.json"))
}
pub fn load() -> Result<Self> {
match File::open(Self::get_cache_file_path()?) {
Ok(file) => Ok(serde_json::from_reader(file)?),
Err(_) => Ok(Default::default()),
}
}
pub fn save(&self) -> Result<()> {
let file = File::create(Self::get_cache_file_path()?)?;
serde_json::to_writer_pretty(file, self)?;
Ok(())
}
pub fn find_book_source_index(
&self,
book_source_url: &str,
book_source_name: &str,
) -> Option<usize> {
self.book_sources.iter().position(|item| {
item.book_source_url == book_source_url && item.book_source_name == book_source_name
})
}
pub fn add_book_source(&mut self, book_source: BookSource) {
if let Some(index) =
self.find_book_source_index(&book_source.book_source_url, &book_source.book_source_name)
{
self.book_sources.remove(index);
}
self.book_sources.push(book_source);
}
pub fn find_book_source(
&self,
book_source_url: &str,
book_source_name: &str,
) -> Option<&BookSource> {
self.book_sources.iter().find(|bs| {
bs.book_source_url == book_source_url && bs.book_source_name == book_source_name
})
}
}
impl Deref for BookSourceCache {
type Target = Vec<BookSource>;
fn deref(&self) -> &Self::Target {
&self.book_sources
}
}
impl DerefMut for BookSourceCache {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.book_sources
}
}
impl Drop for BookSourceCache {
fn drop(&mut self) {
self.save().expect("save book source cache failed");
}
}