Extractor rewrite
This commit is contained in:
121
crates/pile-value/src/source/misc.rs
Normal file
121
crates/pile-value/src/source/misc.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Returns the age of a path as a [DateTime].
|
||||
/// - If the path doesn't exist, returns [None]
|
||||
/// - If it's a file, returns the modified time
|
||||
/// - If it's a directory, returns the LATEST modified time of all files within
|
||||
pub fn path_ts_latest(path: impl AsRef<Path>) -> Result<Option<DateTime<Utc>>, std::io::Error> {
|
||||
let path = path.as_ref();
|
||||
if !path.exists() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let metadata = fs::metadata(path)?;
|
||||
|
||||
if metadata.is_file() {
|
||||
let modified = metadata.modified()?;
|
||||
Ok(Some(modified.into()))
|
||||
} else if metadata.is_dir() {
|
||||
find_latest_modified(path)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the age of a path as a [DateTime].
|
||||
/// - If the path doesn't exist, returns [None]
|
||||
/// - If it's a file, returns the modified time
|
||||
/// - If it's a directory, returns the EARLIEST modified time of all files within
|
||||
pub fn path_ts_earliest(path: impl AsRef<Path>) -> Result<Option<DateTime<Utc>>, std::io::Error> {
|
||||
let path = path.as_ref();
|
||||
if !path.exists() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let metadata = fs::metadata(path)?;
|
||||
|
||||
if metadata.is_file() {
|
||||
let modified = metadata.modified()?;
|
||||
Ok(Some(modified.into()))
|
||||
} else if metadata.is_dir() {
|
||||
find_earliest_modified(path)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn find_latest_modified(dir: &Path) -> Result<Option<DateTime<Utc>>, std::io::Error> {
|
||||
let mut latest: Option<DateTime<Utc>> = None;
|
||||
|
||||
// Include the directory's own modification time
|
||||
let dir_metadata = fs::metadata(dir)?;
|
||||
if let Ok(modified) = dir_metadata.modified() {
|
||||
let dt: DateTime<Utc> = modified.into();
|
||||
latest = Some(dt);
|
||||
}
|
||||
|
||||
let entries = fs::read_dir(dir)?;
|
||||
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let metadata = entry.metadata()?;
|
||||
|
||||
if metadata.is_file() {
|
||||
if let Ok(modified) = metadata.modified() {
|
||||
let dt: DateTime<Utc> = modified.into();
|
||||
latest = Some(match latest {
|
||||
Some(prev) if prev > dt => prev,
|
||||
_ => dt,
|
||||
});
|
||||
}
|
||||
} else if metadata.is_dir()
|
||||
&& let Some(dir_latest) = find_latest_modified(&path)?
|
||||
{
|
||||
latest = Some(match latest {
|
||||
Some(prev) if prev > dir_latest => prev,
|
||||
_ => dir_latest,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(latest);
|
||||
}
|
||||
|
||||
fn find_earliest_modified(dir: &Path) -> Result<Option<DateTime<Utc>>, std::io::Error> {
|
||||
let mut earliest: Option<DateTime<Utc>> = None;
|
||||
|
||||
// Include the directory's own modification time
|
||||
let dir_metadata = fs::metadata(dir)?;
|
||||
if let Ok(modified) = dir_metadata.modified() {
|
||||
let dt: DateTime<Utc> = modified.into();
|
||||
earliest = Some(dt);
|
||||
}
|
||||
|
||||
let entries = fs::read_dir(dir)?;
|
||||
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let metadata = entry.metadata()?;
|
||||
|
||||
if metadata.is_file() {
|
||||
if let Ok(modified) = metadata.modified() {
|
||||
let dt: DateTime<Utc> = modified.into();
|
||||
earliest = Some(match earliest {
|
||||
Some(prev) if prev < dt => prev,
|
||||
_ => dt,
|
||||
});
|
||||
}
|
||||
} else if metadata.is_dir()
|
||||
&& let Some(dir_earliest) = find_earliest_modified(&path)?
|
||||
{
|
||||
earliest = Some(match earliest {
|
||||
Some(prev) if prev < dir_earliest => prev,
|
||||
_ => dir_earliest,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(earliest);
|
||||
}
|
||||
Reference in New Issue
Block a user