use std::collections::HashSet; use std::collections::hash_set::Iter; use std::fs::OpenOptions; use std::hash::Hash; use std::io::Read; use std::path::Path; use std::sync::{Arc, Mutex}; use path::{PathHandled, PathHandler}; use serde::{Deserialize, Serialize}; use crate::Error; #[derive(Debug, Clone, Default, Deserialize, Serialize)] pub struct Lock { #[serde(skip_deserializing, skip_serializing)] ph: Option>>, inner: HashSet, } impl Lock where T: Lockable + Status + Deserialize<'de>, { pub fn new(ph: Arc>, inner: HashSet) -> Self { Self { ph: Some(ph), inner, } } pub fn load

(ph: Arc>, path: P) -> crate::Result where P: AsRef, { let mut path = path.as_ref().to_path_buf(); if path.is_relative() { path = path.canonicalize()?; } let mut buf = Vec::new(); OpenOptions::new() .read(true) .open(path)? .read_to_end(&mut buf)?; let lock: Lock = toml::from_slice(buf.as_slice())?; Ok(lock) } pub fn update(&mut self) -> crate::Result<()> { let ph = self.ph.as_ref().ok_or(Error::MissingPathHandler)?.clone(); self.inner = self .inner .clone() .into_iter() .filter_map(|mut item| { let item = item.with_path_handler(Arc::clone(&ph)); // If the class is up-to-date and no errors occurred during the check if item.is_updated().is_ok_and(|b| b == true) { Some(item.to_owned()) } else { None } }) .collect(); Ok(()) } pub fn set_path_handler(&mut self, ph: Arc>) { self.ph = Some(ph); } pub fn with_path_handler(&mut self, ph: Arc>) -> &mut Self { self.ph = Some(ph); self } /// Iterates over the entries in `NestLock`. pub fn iter(&self) -> Iter<'_, T> { self.inner.iter() } pub fn insert(&mut self, class: T) -> bool { self.inner.insert(class) } } pub trait Lockable: Hash + Eq + Clone + PathHandled {} trait Status { type Error; fn is_updated(&self) -> Result; }