Skip to content

Commit

Permalink
refactor: to filetime for platform-agnostic atime, ctime, mtime inspe…
Browse files Browse the repository at this point in the history
…ction
  • Loading branch information
simonsan committed May 28, 2023
1 parent 96c3d95 commit f4a9cfa
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 21 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ open = "4.1.0"
winnow = "0.4.6"
byte-unit = "4.0.19"

# date related
filetime = "0.2.21"

# infer file and MIME type by magic number
infer = "0.13"
Expand Down Expand Up @@ -159,6 +161,7 @@ dialoguer = { workspace = true }
ron = { workspace = true }
open = { workspace = true }


[dev-dependencies]
abscissa_core = { workspace = true, features = ["testing"] }
once_cell = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

1. implement Terminal UI
- generate config interactively `generate config --interactive`
- <https://crates.io/crates/ratatui/0.20.1> + <https://crates.io/crates/tui-react>

1. implement scripting
1. build GUI
Expand Down
1 change: 1 addition & 0 deletions crates/organize-rs_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ winnow = { workspace = true }
byte-unit = { workspace = true }
trash = { workspace = true }
rayon = { workspace = true }
filetime = { workspace = true }

[dev-dependencies]
rustup-toolchain = "0.1.4"
Expand Down
24 changes: 11 additions & 13 deletions crates/organize-rs_core/src/filters/impl_.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use chrono::{DateTime, Utc};

use filetime::FileTime;
use itertools::Itertools;
use jwalk::{ClientState, DirEntry};

Expand Down Expand Up @@ -198,9 +199,8 @@ impl FilterKind {
) -> Box<dyn FnMut(&DirEntry<C>) -> bool + 'args> {
Box::new(|entry| {
entry.metadata().ok().map_or(false, |metadata| {
metadata.accessed().map_or(false, |sys_time| {
Self::matches_date(&sys_time, &range.clone())
})
let atime = FileTime::from_last_access_time(&metadata);
Self::matches_date(&atime, &range.clone())
})
})
}
Expand All @@ -210,30 +210,28 @@ impl FilterKind {
) -> Box<dyn FnMut(&DirEntry<C>) -> bool + 'args> {
Box::new(|entry| {
entry.metadata().ok().map_or(false, |metadata| {
metadata.modified().map_or(false, |sys_time| {
Self::matches_date(&sys_time, &range.clone())
})
let mtime = FileTime::from_last_modification_time(&metadata);
Self::matches_date(&mtime, &range.clone())
})
})
}

fn filter_by_created<'a, 'args, C: ClientState>(
&'a self,
range: &'args PeriodRange,
) -> Box<dyn FnMut(&DirEntry<C>) -> bool + 'args> {
Box::new(|entry| {
entry.metadata().ok().map_or(false, |metadata| {
metadata.created().map_or(false, |sys_time| {
Self::matches_date(&sys_time, &range.clone())
})
FileTime::from_creation_time(&metadata)
.map_or(false, |ctime| Self::matches_date(&ctime, &range.clone()))
})
})
}

fn matches_date(item_date: &std::time::SystemTime, range: &PeriodRange) -> bool {
let datetime_file: DateTime<Utc> = chrono::DateTime::from(*item_date);
let now = chrono::offset::Utc::now();
fn matches_date(item_date: &FileTime, range: &PeriodRange) -> bool {
let now = FileTime::now();

let seconds_since_created = match u64::try_from((now - datetime_file).num_seconds()) {
let seconds_since_created = match u64::try_from(now.seconds() - item_date.seconds()) {
Ok(it) => it,
Err(err) => {
eprintln!("subtraction of two datetimes can't be negative: {err}");
Expand Down
35 changes: 27 additions & 8 deletions crates/organize-rs_core/src/filters/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ fn empty_file() -> Vec<PathBuf> {
#[fixture]
fn size() -> Vec<PathBuf> {
vec![
get_fixtures_dir().join("different_sizes"),
get_fixtures_dir().join("different_sizes").join("1MiB"),
get_fixtures_dir().join("different_sizes").join("300KiB"),
get_fixtures_dir().join("different_sizes").join("empty.txt"),
get_fixtures_dir().join("size_based"),
get_fixtures_dir().join("size_based").join("1MiB"),
get_fixtures_dir().join("size_based").join("300KiB"),
get_fixtures_dir().join("size_based").join("empty.txt"),
]
}

Expand Down Expand Up @@ -133,9 +133,28 @@ fn get_fixture_entries(sub_dir: impl AsRef<Path>) -> Vec<DirEntry<((), ())>> {
.collect_vec()
}

#[rstest]
fn test_filter_file_date_7d_passes(mut size: Vec<PathBuf>) {
let filter = FilterKind::Size {
range: SizeRange::from_str("..2mb").unwrap(),
};

let mut entries = get_fixture_entries("date_based");
let paths = entries.iter().map(|f| f.path()).collect_vec();
assert_eq!(entries.len(), size.len());
assert_eq!(paths, size);
entries.retain(|f| (filter.get_filter()(f)));
let paths = entries.iter().map(|f| f.path()).collect_vec();

_ = size.remove(0);

assert_eq!(entries.len(), size.len());
assert_eq!(paths, size);
}

#[rstest]
#[should_panic]
fn test_filter_mimetype_image_passes(mut mimetype: Vec<PathBuf>) {
fn test_filter_mimetype_image_fails(mut mimetype: Vec<PathBuf>) {
let filter = FilterKind::Mimetype {
mimetype: vec![String::from("image")],
};
Expand Down Expand Up @@ -522,7 +541,7 @@ fn test_filter_file_size_2mb_passes(mut size: Vec<PathBuf>) {
range: SizeRange::from_str("..2mb").unwrap(),
};

let mut entries = get_fixture_entries("different_sizes");
let mut entries = get_fixture_entries("size_based");
let paths = entries.iter().map(|f| f.path()).collect_vec();
assert_eq!(entries.len(), size.len());
assert_eq!(paths, size);
Expand All @@ -541,7 +560,7 @@ fn test_filter_file_size_350_800_kib_passes(mut size: Vec<PathBuf>) {
range: SizeRange::from_str("350KiB..800kib").unwrap(),
};

let mut entries = get_fixture_entries("different_sizes");
let mut entries = get_fixture_entries("size_based");
let paths = entries.iter().map(|f| f.path()).collect_vec();
assert_eq!(entries.len(), size.len());
assert_eq!(paths, size);
Expand All @@ -559,7 +578,7 @@ fn test_filter_file_size_250kib_passes(mut size: Vec<PathBuf>) {
range: SizeRange::from_str("250KiB..").unwrap(),
};

let mut entries = get_fixture_entries("different_sizes");
let mut entries = get_fixture_entries("size_based");
let paths = entries.iter().map(|f| f.path()).collect_vec();
assert_eq!(entries.len(), size.len());
assert_eq!(paths, size);
Expand Down
Empty file removed tests/fixtures/.gitkeep
Empty file.

0 comments on commit f4a9cfa

Please sign in to comment.