A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
1.3 KiB

7 years ago
7 years ago
5 years ago
7 years ago
7 years ago
4 years ago
7 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
5 years ago
7 years ago
  1. use std::error::Error;
  2. use std::fs::read_dir;
  3. use std::path::Path;
  4. use std::rc::Rc;
  5. use std::str::FromStr;
  6. use std::time::{SystemTime, UNIX_EPOCH};
  7. pub trait Storage {
  8. fn write_filename(&self) -> Box<Path>;
  9. fn read_filename(&self) -> Result<Box<Path>, Box<dyn Error>>;
  10. fn recent_date(&self) -> Result<u64, Box<dyn Error>>;
  11. }
  12. #[derive(Debug, Clone)]
  13. pub struct SimpleStorage(Rc<Path>);
  14. impl SimpleStorage {
  15. #[must_use]
  16. pub const fn new(base: Rc<Path>) -> Self {
  17. Self(base)
  18. }
  19. fn get_path(&self, date: u64) -> Box<Path> {
  20. self.0.join(date.to_string()).into()
  21. }
  22. }
  23. impl Storage for SimpleStorage {
  24. fn write_filename(&self) -> Box<Path> {
  25. self.get_path(
  26. SystemTime::now()
  27. .duration_since(UNIX_EPOCH)
  28. .unwrap()
  29. .as_secs(),
  30. )
  31. }
  32. fn read_filename(&self) -> Result<Box<Path>, Box<dyn Error>> {
  33. Ok(self.get_path(self.recent_date()?))
  34. }
  35. fn recent_date(&self) -> Result<u64, Box<dyn Error>> {
  36. read_dir(&self.0)?
  37. .map(|entry| {
  38. entry
  39. .ok()
  40. .and_then(|e| e.file_name().into_string().ok())
  41. .and_then(|filename| u64::from_str(&filename).ok())
  42. })
  43. .fold(None, |maybe_newest, maybe_time| {
  44. maybe_newest.into_iter().chain(maybe_time).max()
  45. })
  46. .ok_or_else(|| "Not found".to_string().into())
  47. }
  48. }