use std::error::Error; use std::fs::read_dir; use std::path::Path; use std::rc::Rc; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; pub trait Storage { fn write_filename(&self) -> Box; fn read_filename(&self) -> Result, Box>; fn recent_date(&self) -> Result>; } #[derive(Debug, Clone)] pub struct SimpleStorage(Rc); impl SimpleStorage { #[must_use] pub const fn new(base: Rc) -> Self { Self(base) } fn get_path(&self, date: u64) -> Box { self.0.join(date.to_string()).into() } } impl Storage for SimpleStorage { fn write_filename(&self) -> Box { self.get_path( SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(), ) } fn read_filename(&self) -> Result, Box> { Ok(self.get_path(self.recent_date()?)) } fn recent_date(&self) -> Result> { read_dir(&self.0)? .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()) } }