use std::ops::Not;
use std::path::{Path, PathBuf};
use chrono::{DateTime, Datelike, Local};
use crate::error::InvalidArgumentError;
#[derive(PartialEq)]
pub enum DirectoryDateType {
YYYYMMDD,
YYYYMM,
YYYY,
}
impl DirectoryDateType {
pub fn generate_path_string(&self, date: &DateTime<Local>, separator: Option<&str>) -> String {
let mut path: Vec<String> = vec![];
path.push(date.year().to_string());
self.insert_separator(&mut path, separator);
if *self != DirectoryDateType::YYYY {
path.push(format!("{:0>2}", date.month()));
self.insert_separator(&mut path, separator);
}
if *self == DirectoryDateType::YYYYMMDD {
path.push(format!("{:0>2}", date.day().to_string()));
}
return path.join("");
}
#[inline]
fn insert_separator(&self, path: &mut Vec<String>, separator: Option<&str>) {
if separator.is_none() {
return;
}
path.push(separator.unwrap().to_owned());
}
}
pub fn generate_path(
parent_path: &Path,
date_type: DirectoryDateType,
separator: Option<&str>,
) -> Result<Box<Path>, InvalidArgumentError> {
if parent_path.exists().not() {
let path_str = parent_path.as_os_str();
let message = format!("[{:?}] 경로가 존재하지 않습니다.", path_str);
return Err(InvalidArgumentError::new(message.as_str()));
}
let now = Local::now();
let dir_string = date_type.generate_path_string(&now, separator);
let result = PathBuf::from(parent_path).join(dir_string);
if !&result.exists() {
let created_result = std::fs::create_dir_all(&result);
if created_result.is_err() {
let err = created_result.err();
return Err(InvalidArgumentError::new(
format!("{:?}", err.unwrap()).as_str(),
));
}
}
return Ok(result.into_boxed_path());
}
#[cfg(test)]
mod tests {
use crate::io_util::{generate_path, DirectoryDateType};
use std::path::Path;
#[test]
fn generate_path_test() {
let now = chrono::Local::now();
let compare_dir_name = DirectoryDateType::YYYYMMDD.generate_path_string(&now, Some("_"));
let current_path = Path::new(env!("CARGO_MANIFEST_DIR"));
let result = generate_path(current_path, DirectoryDateType::YYYYMMDD, Some("_"));
assert!(result.is_ok());
let created_dir = result.unwrap();
assert!(created_dir.exists());
let dir_name = created_dir.file_name().unwrap();
assert_eq!(dir_name.to_str().unwrap(), compare_dir_name);
let deleted_dir = std::fs::remove_dir(created_dir);
assert!(deleted_dir.is_ok());
}
}