Skip to content

Commit d7e9b4a

Browse files
committed
♻️ Introduce TimeFilterResolver to unify TimeFilters construction
1 parent be231db commit d7e9b4a

File tree

5 files changed

+117
-200
lines changed

5 files changed

+117
-200
lines changed

cli/src/command/append.rs

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
Command, ask_password, check_password,
88
core::{
99
AclStrategy, CreateOptions, KeepOptions, OwnerOptions, PathFilter, PathTransformers,
10-
PathnameEditor, PermissionStrategy, StoreAs, TimeFilter, TimeFilters, TimeOptions,
10+
PathnameEditor, PermissionStrategy, StoreAs, TimeFilterResolver, TimeOptions,
1111
TimestampStrategy, XattrStrategy, collect_items, create_entry, entry_option,
1212
re::{bsd::SubstitutionRule, gnu::TransformRule},
1313
read_paths, read_paths_stdin,
@@ -355,44 +355,17 @@ fn append_to_archive(args: AppendCommand) -> anyhow::Result<()> {
355355
atime: args.atime.map(|it| it.to_system_time()),
356356
clamp_atime: args.clamp_atime,
357357
};
358-
let time_filters = TimeFilters {
359-
ctime: TimeFilter {
360-
newer_than: if let Some(p) = &args.newer_ctime_than {
361-
let metadata = fs::metadata(p)?;
362-
Some(metadata.created().map_err(|_| {
363-
std::io::Error::new(
364-
std::io::ErrorKind::Unsupported,
365-
format!("--newer-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
366-
)
367-
})?)
368-
} else {
369-
args.newer_ctime.map(|it| it.to_system_time())
370-
},
371-
older_than: if let Some(p) = &args.older_ctime_than {
372-
let metadata = fs::metadata(p)?;
373-
Some(metadata.created().map_err(|_| {
374-
std::io::Error::new(
375-
std::io::ErrorKind::Unsupported,
376-
format!("--older-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
377-
)
378-
})?)
379-
} else {
380-
args.older_ctime.map(|it| it.to_system_time())
381-
},
382-
},
383-
mtime: TimeFilter {
384-
newer_than: if let Some(p) = &args.newer_mtime_than {
385-
Some(fs::metadata(p)?.modified()?)
386-
} else {
387-
args.newer_mtime.map(|it| it.to_system_time())
388-
},
389-
older_than: if let Some(p) = &args.older_mtime_than {
390-
Some(fs::metadata(p)?.modified()?)
391-
} else {
392-
args.older_mtime.map(|it| it.to_system_time())
393-
},
394-
},
395-
};
358+
let time_filters = TimeFilterResolver {
359+
newer_ctime_than: args.newer_ctime_than.as_deref(),
360+
older_ctime_than: args.older_ctime_than.as_deref(),
361+
newer_ctime: args.newer_ctime.map(|it| it.to_system_time()),
362+
older_ctime: args.older_ctime.map(|it| it.to_system_time()),
363+
newer_mtime_than: args.newer_mtime_than.as_deref(),
364+
older_mtime_than: args.older_mtime_than.as_deref(),
365+
newer_mtime: args.newer_mtime.map(|it| it.to_system_time()),
366+
older_mtime: args.older_mtime.map(|it| it.to_system_time()),
367+
}
368+
.resolve()?;
396369
let create_options = CreateOptions {
397370
option,
398371
keep_options,

cli/src/command/core.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,59 @@ use std::{
2727
};
2828
pub(crate) use time_filter::{TimeFilter, TimeFilters};
2929

30+
/// Resolves CLI time filter options into a `TimeFilters` instance.
31+
/// Path arguments (`*_than`) take precedence over direct `SystemTime` values.
32+
pub(crate) struct TimeFilterResolver<'a> {
33+
pub(crate) newer_ctime_than: Option<&'a Path>,
34+
pub(crate) older_ctime_than: Option<&'a Path>,
35+
pub(crate) newer_ctime: Option<SystemTime>,
36+
pub(crate) older_ctime: Option<SystemTime>,
37+
pub(crate) newer_mtime_than: Option<&'a Path>,
38+
pub(crate) older_mtime_than: Option<&'a Path>,
39+
pub(crate) newer_mtime: Option<SystemTime>,
40+
pub(crate) older_mtime: Option<SystemTime>,
41+
}
42+
43+
impl TimeFilterResolver<'_> {
44+
/// Resolves file paths and times into a `TimeFilters` instance.
45+
pub(crate) fn resolve(self) -> io::Result<TimeFilters> {
46+
fn resolve_ctime(path: &Path) -> io::Result<SystemTime> {
47+
fs::metadata(path)?.created().map_err(|_| {
48+
io::Error::new(
49+
io::ErrorKind::Unsupported,
50+
format!(
51+
"creation time (birth time) is not available for '{}'",
52+
path.display()
53+
),
54+
)
55+
})
56+
}
57+
58+
Ok(TimeFilters {
59+
ctime: TimeFilter {
60+
newer_than: match self.newer_ctime_than {
61+
Some(p) => Some(resolve_ctime(p)?),
62+
None => self.newer_ctime,
63+
},
64+
older_than: match self.older_ctime_than {
65+
Some(p) => Some(resolve_ctime(p)?),
66+
None => self.older_ctime,
67+
},
68+
},
69+
mtime: TimeFilter {
70+
newer_than: match self.newer_mtime_than {
71+
Some(p) => Some(fs::metadata(p)?.modified()?),
72+
None => self.newer_mtime,
73+
},
74+
older_than: match self.older_mtime_than {
75+
Some(p) => Some(fs::metadata(p)?.modified()?),
76+
None => self.older_mtime,
77+
},
78+
},
79+
})
80+
}
81+
}
82+
3083
/// Overhead for a split archive part in bytes, including PNA header, AHED, ANXT, and AEND chunks.
3184
pub(crate) const SPLIT_ARCHIVE_OVERHEAD_BYTES: usize =
3285
PNA_HEADER.len() + MIN_CHUNK_BYTES_SIZE * 3 + 8;

cli/src/command/create.rs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{
77
Command, ask_password, check_password,
88
core::{
99
AclStrategy, CreateOptions, KeepOptions, MIN_SPLIT_PART_BYTES, OwnerOptions,
10-
PathFilter, PathTransformers, PathnameEditor, PermissionStrategy, StoreAs, TimeFilter,
11-
TimeFilters, TimeOptions, TimestampStrategy, XattrStrategy, collect_items,
10+
PathFilter, PathTransformers, PathnameEditor, PermissionStrategy, StoreAs,
11+
TimeFilterResolver, TimeOptions, TimestampStrategy, XattrStrategy, collect_items,
1212
create_entry, entry_option,
1313
re::{bsd::SubstitutionRule, gnu::TransformRule},
1414
read_paths, read_paths_stdin, write_split_archive,
@@ -385,44 +385,17 @@ fn create_archive(args: CreateCommand) -> anyhow::Result<()> {
385385
if let Some(working_dir) = args.working_dir {
386386
env::set_current_dir(working_dir)?;
387387
}
388-
let time_filters = TimeFilters {
389-
ctime: TimeFilter {
390-
newer_than: if let Some(p) = &args.newer_ctime_than {
391-
let metadata = fs::metadata(p)?;
392-
Some(metadata.created().map_err(|_| {
393-
std::io::Error::new(
394-
std::io::ErrorKind::Unsupported,
395-
format!("--newer-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
396-
)
397-
})?)
398-
} else {
399-
args.newer_ctime.map(|it| it.to_system_time())
400-
},
401-
older_than: if let Some(p) = &args.older_ctime_than {
402-
let metadata = fs::metadata(p)?;
403-
Some(metadata.created().map_err(|_| {
404-
std::io::Error::new(
405-
std::io::ErrorKind::Unsupported,
406-
format!("--older-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
407-
)
408-
})?)
409-
} else {
410-
args.older_ctime.map(|it| it.to_system_time())
411-
},
412-
},
413-
mtime: TimeFilter {
414-
newer_than: if let Some(p) = &args.newer_mtime_than {
415-
Some(fs::metadata(p)?.modified()?)
416-
} else {
417-
args.newer_mtime.map(|it| it.to_system_time())
418-
},
419-
older_than: if let Some(p) = &args.older_mtime_than {
420-
Some(fs::metadata(p)?.modified()?)
421-
} else {
422-
args.older_mtime.map(|it| it.to_system_time())
423-
},
424-
},
425-
};
388+
let time_filters = TimeFilterResolver {
389+
newer_ctime_than: args.newer_ctime_than.as_deref(),
390+
older_ctime_than: args.older_ctime_than.as_deref(),
391+
newer_ctime: args.newer_ctime.map(|it| it.to_system_time()),
392+
older_ctime: args.older_ctime.map(|it| it.to_system_time()),
393+
newer_mtime_than: args.newer_mtime_than.as_deref(),
394+
older_mtime_than: args.older_mtime_than.as_deref(),
395+
newer_mtime: args.newer_mtime.map(|it| it.to_system_time()),
396+
older_mtime: args.older_mtime.map(|it| it.to_system_time()),
397+
}
398+
.resolve()?;
426399
let target_items = collect_items(
427400
&files,
428401
!args.no_recursive,

cli/src/command/stdio.rs

Lines changed: 25 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::{
99
ask_password, check_password,
1010
core::{
1111
AclStrategy, CreateOptions, KeepOptions, OwnerOptions, PathFilter, PathTransformers,
12-
PathnameEditor, PermissionStrategy, TimeFilter, TimeFilters, TimeOptions,
13-
TimestampStrategy, XattrStrategy, collect_items, collect_split_archives, entry_option,
12+
PathnameEditor, PermissionStrategy, TimeFilterResolver, TimeOptions, TimestampStrategy,
13+
XattrStrategy, collect_items, collect_split_archives, entry_option,
1414
path_lock::PathLocks,
1515
re::{bsd::SubstitutionRule, gnu::TransformRule},
1616
read_paths,
@@ -23,7 +23,7 @@ use crate::{
2323
};
2424
use clap::{ArgGroup, Args, ValueHint};
2525
use pna::Archive;
26-
use std::{env, fs, io, path::PathBuf, sync::Arc, time::SystemTime};
26+
use std::{env, io, path::PathBuf, sync::Arc, time::SystemTime};
2727

2828
#[derive(Args, Clone, Debug)]
2929
#[clap(disable_help_flag = true)]
@@ -484,44 +484,17 @@ fn run_create_archive(args: StdioCommand) -> anyhow::Result<()> {
484484
if let Some(working_dir) = args.working_dir {
485485
env::set_current_dir(working_dir)?;
486486
}
487-
let time_filters = TimeFilters {
488-
ctime: TimeFilter {
489-
newer_than: if let Some(p) = &args.newer_ctime_than {
490-
let metadata = fs::metadata(p)?;
491-
Some(metadata.created().map_err(|_| {
492-
std::io::Error::new(
493-
std::io::ErrorKind::Unsupported,
494-
format!("--newer-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
495-
)
496-
})?)
497-
} else {
498-
args.newer_ctime.map(|it| it.to_system_time())
499-
},
500-
older_than: if let Some(p) = &args.older_ctime_than {
501-
let metadata = fs::metadata(p)?;
502-
Some(metadata.created().map_err(|_| {
503-
std::io::Error::new(
504-
std::io::ErrorKind::Unsupported,
505-
format!("--older-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
506-
)
507-
})?)
508-
} else {
509-
args.older_ctime.map(|it| it.to_system_time())
510-
},
511-
},
512-
mtime: TimeFilter {
513-
newer_than: if let Some(p) = &args.newer_mtime_than {
514-
Some(fs::metadata(p)?.modified()?)
515-
} else {
516-
args.newer_mtime.map(|it| it.to_system_time())
517-
},
518-
older_than: if let Some(p) = &args.older_mtime_than {
519-
Some(fs::metadata(p)?.modified()?)
520-
} else {
521-
args.older_mtime.map(|it| it.to_system_time())
522-
},
523-
},
524-
};
487+
let time_filters = TimeFilterResolver {
488+
newer_ctime_than: args.newer_ctime_than.as_deref(),
489+
older_ctime_than: args.older_ctime_than.as_deref(),
490+
newer_ctime: args.newer_ctime.map(|it| it.to_system_time()),
491+
older_ctime: args.older_ctime.map(|it| it.to_system_time()),
492+
newer_mtime_than: args.newer_mtime_than.as_deref(),
493+
older_mtime_than: args.older_mtime_than.as_deref(),
494+
newer_mtime: args.newer_mtime.map(|it| it.to_system_time()),
495+
older_mtime: args.older_mtime.map(|it| it.to_system_time()),
496+
}
497+
.resolve()?;
525498
let target_items = collect_items(
526499
&files,
527500
!args.no_recursive,
@@ -812,44 +785,17 @@ fn run_append(args: StdioCommand) -> anyhow::Result<()> {
812785
if let Some(working_dir) = args.working_dir {
813786
env::set_current_dir(working_dir)?;
814787
}
815-
let time_filters = TimeFilters {
816-
ctime: TimeFilter {
817-
newer_than: if let Some(p) = &args.newer_ctime_than {
818-
let metadata = fs::metadata(p)?;
819-
Some(metadata.created().map_err(|_| {
820-
std::io::Error::new(
821-
std::io::ErrorKind::Unsupported,
822-
format!("--newer-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
823-
)
824-
})?)
825-
} else {
826-
args.newer_ctime.map(|it| it.to_system_time())
827-
},
828-
older_than: if let Some(p) = &args.older_ctime_than {
829-
let metadata = fs::metadata(p)?;
830-
Some(metadata.created().map_err(|_| {
831-
std::io::Error::new(
832-
std::io::ErrorKind::Unsupported,
833-
format!("--older-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
834-
)
835-
})?)
836-
} else {
837-
args.older_ctime.map(|it| it.to_system_time())
838-
},
839-
},
840-
mtime: TimeFilter {
841-
newer_than: if let Some(p) = &args.newer_mtime_than {
842-
Some(fs::metadata(p)?.modified()?)
843-
} else {
844-
args.newer_mtime.map(|it| it.to_system_time())
845-
},
846-
older_than: if let Some(p) = &args.older_mtime_than {
847-
Some(fs::metadata(p)?.modified()?)
848-
} else {
849-
args.older_mtime.map(|it| it.to_system_time())
850-
},
851-
},
852-
};
788+
let time_filters = TimeFilterResolver {
789+
newer_ctime_than: args.newer_ctime_than.as_deref(),
790+
older_ctime_than: args.older_ctime_than.as_deref(),
791+
newer_ctime: args.newer_ctime.map(|it| it.to_system_time()),
792+
older_ctime: args.older_ctime.map(|it| it.to_system_time()),
793+
newer_mtime_than: args.newer_mtime_than.as_deref(),
794+
older_mtime_than: args.older_mtime_than.as_deref(),
795+
newer_mtime: args.newer_mtime.map(|it| it.to_system_time()),
796+
older_mtime: args.older_mtime.map(|it| it.to_system_time()),
797+
}
798+
.resolve()?;
853799
if let Some(file) = &archive_path {
854800
let archive = open_archive_then_seek_to_end(file)?;
855801
let target_items = collect_items(

cli/src/command/update.rs

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ use crate::{
1111
Command, ask_password, check_password,
1212
core::{
1313
AclStrategy, CreateOptions, KeepOptions, OwnerOptions, PathFilter, PathTransformers,
14-
PathnameEditor, PermissionStrategy, TimeFilter, TimeFilters, TimeOptions,
15-
TimestampStrategy, TransformStrategy, TransformStrategyKeepSolid,
16-
TransformStrategyUnSolid, XattrStrategy, collect_items, collect_split_archives,
17-
create_entry, entry_option,
14+
PathnameEditor, PermissionStrategy, TimeFilterResolver, TimeOptions, TimestampStrategy,
15+
TransformStrategy, TransformStrategyKeepSolid, TransformStrategyUnSolid, XattrStrategy,
16+
collect_items, collect_split_archives, create_entry, entry_option,
1817
re::{bsd::SubstitutionRule, gnu::TransformRule},
1918
read_paths, read_paths_stdin,
2019
},
@@ -365,44 +364,17 @@ fn update_archive<Strategy: TransformStrategy>(args: UpdateCommand) -> anyhow::R
365364
atime: args.atime.map(|it| it.to_system_time()),
366365
clamp_atime: args.clamp_atime,
367366
};
368-
let time_filters = TimeFilters {
369-
ctime: TimeFilter {
370-
newer_than: if let Some(p) = &args.newer_ctime_than {
371-
let metadata = fs::metadata(p)?;
372-
Some(metadata.created().map_err(|_| {
373-
std::io::Error::new(
374-
std::io::ErrorKind::Unsupported,
375-
format!("--newer-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
376-
)
377-
})?)
378-
} else {
379-
args.newer_ctime.map(|it| it.to_system_time())
380-
},
381-
older_than: if let Some(p) = &args.older_ctime_than {
382-
let metadata = fs::metadata(p)?;
383-
Some(metadata.created().map_err(|_| {
384-
std::io::Error::new(
385-
std::io::ErrorKind::Unsupported,
386-
format!("--older-ctime-than requires filesystem support for creation time (birth time), which is not available for '{}'", p.display())
387-
)
388-
})?)
389-
} else {
390-
args.older_ctime.map(|it| it.to_system_time())
391-
},
392-
},
393-
mtime: TimeFilter {
394-
newer_than: if let Some(p) = &args.newer_mtime_than {
395-
Some(fs::metadata(p)?.modified()?)
396-
} else {
397-
args.newer_mtime.map(|it| it.to_system_time())
398-
},
399-
older_than: if let Some(p) = &args.older_mtime_than {
400-
Some(fs::metadata(p)?.modified()?)
401-
} else {
402-
args.older_mtime.map(|it| it.to_system_time())
403-
},
404-
},
405-
};
367+
let time_filters = TimeFilterResolver {
368+
newer_ctime_than: args.newer_ctime_than.as_deref(),
369+
older_ctime_than: args.older_ctime_than.as_deref(),
370+
newer_ctime: args.newer_ctime.map(|it| it.to_system_time()),
371+
older_ctime: args.older_ctime.map(|it| it.to_system_time()),
372+
newer_mtime_than: args.newer_mtime_than.as_deref(),
373+
older_mtime_than: args.older_mtime_than.as_deref(),
374+
newer_mtime: args.newer_mtime.map(|it| it.to_system_time()),
375+
older_mtime: args.older_mtime.map(|it| it.to_system_time()),
376+
}
377+
.resolve()?;
406378
let create_options = CreateOptions {
407379
option,
408380
keep_options,

0 commit comments

Comments
 (0)