1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use std::{cmp::Ordering, path::PathBuf};
use strum::{AsRefStr, EnumIter, EnumString, EnumVariantNames};
pub mod cli;
pub trait IterExt: Iterator + Sized {
fn max_by_maybe_key<F, K>(self, key_fn: F) -> Option<Self::Item>
where
F: Fn(&Self::Item) -> Option<K>,
K: Ord,
{
let winner = self
.filter_map(|path| {
let key = key_fn(&path)?;
Some((path, key))
})
.reduce(|winner, challenger| match winner.1.cmp(&challenger.1) {
Ordering::Greater => winner,
Ordering::Equal | Ordering::Less => challenger,
})?;
Some(winner.0)
}
}
impl<T> IterExt for T where T: Iterator + Sized {}
#[derive(Debug, EnumString, EnumVariantNames, AsRefStr, EnumIter)]
#[strum(serialize_all = "kebab_case")]
pub enum Method {
Accessed,
Created,
Modified,
}
pub trait MostRecently: Iterator<Item = PathBuf> + Sized {
fn most_recently(self, method: Method) -> Option<Self::Item> {
match method {
Method::Accessed => {
self.max_by_maybe_key(|path_buf| path_buf.metadata().ok()?.accessed().ok())
}
Method::Created => {
self.max_by_maybe_key(|path_buf| path_buf.metadata().ok()?.created().ok())
}
Method::Modified => {
self.max_by_maybe_key(|path_buf| path_buf.metadata().ok()?.modified().ok())
}
}
}
}
impl<T> MostRecently for T where T: Iterator<Item = PathBuf> {}