use anyhow::Result;
use chrono::prelude::*;
use std::path::PathBuf;
pub trait FileTree {
fn basepath_fileprefix(&mut self, file_suffix: &str) -> Result<(PathBuf, PathBuf)>;
}
pub struct DateTimeDirTree<'a> {
basepath_fmt: &'a str,
filename_prefix_fmt: &'a str,
timestamp: Option<DateTime<Local>>,
}
impl<'a> DateTimeDirTree<'a> {
pub fn new(basepath_fmt: &'a str, filename_prefix_fmt: &'a str) -> Self {
Self {
basepath_fmt,
filename_prefix_fmt,
timestamp: None,
}
}
pub fn set_timestamp(&mut self, ts: DateTime<Local>) {
self.timestamp = Some(ts);
}
}
impl<'a> Default for DateTimeDirTree<'a> {
fn default() -> Self {
Self {
basepath_fmt: "%Y/%m/%d/%H/",
filename_prefix_fmt: "%Y-%m-%d_%H-%M-%S-%3f_",
timestamp: None,
}
}
}
impl<'a> FileTree for DateTimeDirTree<'a> {
fn basepath_fileprefix(&mut self, file_suffix: &str) -> Result<(PathBuf, PathBuf)> {
let now = self.timestamp.unwrap_or_else(Local::now);
let basepath = now.format(self.basepath_fmt).to_string();
let filename = now.format(self.filename_prefix_fmt).to_string() + file_suffix;
Ok((basepath.into(), filename.into()))
}
}
#[derive(Default)]
pub struct CountingTree {
dir_counter: usize,
file_counter: usize,
max_in_dir: usize,
pub id: String,
}
impl CountingTree {
pub fn new(max_in_dir: usize) -> Self {
CountingTree {
max_in_dir,
..Default::default()
}
}
}
impl FileTree for CountingTree {
fn basepath_fileprefix(&mut self, file_suffix: &str) -> Result<(PathBuf, PathBuf)> {
let basepath: PathBuf = [self.id.clone(), self.dir_counter.to_string()]
.iter()
.collect();
let filename = self.file_counter.to_string() + file_suffix;
if self.file_counter + 1 > self.max_in_dir {
self.file_counter = 0;
self.dir_counter += 1;
} else {
self.file_counter += 1;
}
Ok((basepath, filename.into()))
}
}