use std::collections::HashSet; use std::collections::hash_set::Iter; use std::fs::{File, OpenOptions}; use std::io::Read; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use path::{PathHandled, PathHandler}; use serde::{Deserialize, Serialize}; use crate::Error; use crate::class::Class; use crate::meta::Meta; use crate::package::Package; #[derive(Debug, Clone, Default, Deserialize, Serialize)] pub struct Prey { package: Package, meta: Meta, } impl Prey { pub fn new(name: S) -> Self { Prey { package: (), meta: (), } } } impl TryFrom for Prey { type Error = Error; fn try_from(value: File) -> Result { let mut value = value; let mut buf = String::new(); value.read_to_string(&mut buf)?; Ok(toml::from_str(buf.as_str())?) } } impl TryFrom for Prey { type Error = Error; fn try_from(value: PathBuf) -> Result { Prey::try_from(OpenOptions::new().read(true).open(value)?) } } #[derive(Debug, Clone, Default, Deserialize, Serialize)] pub struct PreyLock { #[serde(skip_deserializing, skip_serializing)] ph: Option>>, classes: HashSet, } impl PreyLock { pub fn new(ph: Arc>, classes: HashSet) -> Self { Self { ph: Some(ph), classes, } } pub fn update(&mut self) -> crate::Result<()> { let ph = self.ph.as_ref().ok_or(Error::MissingPathHandler)?.clone(); self.classes = self .classes .clone() .into_iter() .filter_map(|mut class| { let class = class.with_path_handler(Arc::clone(&ph)); // If the class is up-to-date and no errors occurred during the check if class.is_updated().is_ok_and(|b| b == true) { Some(class.to_owned()) } else { None } }) .collect(); Ok(()) } /// Iterates over the entries in `PreyLock`. pub fn iter(&self) -> Iter<'_, Class> { self.classes.iter() } pub fn insert(&mut self, class: Class) -> bool { self.classes.insert(class) } } impl TryFrom for PreyLock { type Error = Error; fn try_from(value: File) -> Result { let mut value = value; let mut buf = String::new(); value.read_to_string(&mut buf)?; Ok(toml::from_str(buf.as_str())?) } } impl TryFrom for PreyLock { type Error = Error; fn try_from(value: PathBuf) -> Result { PreyLock::try_from(OpenOptions::new().read(true).open(value)?) } } impl PathHandled for PreyLock { fn set_path_handler(&mut self, ph: Arc>) { self.ph = Some(ph); } fn with_path_handler(&mut self, ph: Arc>) -> &mut Self { self.ph = Some(ph); self } }