use std::error::Error; use std::fs::read_dir; use std::path::PathBuf; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; pub trait Storage { fn write_filename(&self) -> PathBuf; fn read_filename(&self) -> Result>; fn recent_date(&self) -> Result>; } #[derive(Debug, Clone)] pub struct SimpleStorage(PathBuf); impl SimpleStorage { #[must_use] pub const fn new(base: PathBuf) -> Self { Self(base) } fn get_path(&self, date: Option) -> PathBuf { match date { Some(d) => self.0.join(d.to_string()), None => self.0.clone(), } } } impl Storage for SimpleStorage { fn write_filename(&self) -> PathBuf { self.get_path(Some( SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(), )) } fn read_filename(&self) -> Result> { Ok(self.get_path(Some(self.recent_date()?))) } fn recent_date(&self) -> Result> { let dir = self.get_path(None); read_dir(dir)? .map(|entry| { entry .ok() .and_then(|e| e.file_name().into_string().ok()) .and_then(|filename| u64::from_str(&filename).ok()) }) .fold(None, |maybe_newest, maybe_time| { maybe_newest.into_iter().chain(maybe_time).max() }) .ok_or_else(|| "Not found".to_string().into()) } }