use std::error::Error; use std::fs::read_dir; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; pub trait Storage { fn write_filename(&self) -> String; fn read_filename(&self) -> Result>; fn recent_date(&self) -> Result>; } #[derive(Clone)] pub struct SimpleStorage(String, String); impl SimpleStorage { pub fn new(base: String, filename: String) -> Self { SimpleStorage(base, filename) } fn get_path(&self, date: Option) -> String { match date { Some(d) => format!("{}/_{}/{}", self.0, self.1, d), None => format!("{}/_{}", self.0, self.1) } } } impl Storage for SimpleStorage { fn write_filename(&self) -> String { self.get_path(Some(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs())) } fn read_filename(&self) -> Result> { Ok(self.get_path(Some(try!(self.recent_date())))) } fn recent_date(&self) -> Result> { let dir = self.get_path(None); try!(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()) } }