Use the humantime_to_duration crate

This commit is contained in:
Sylvestre Ledru 2023-04-23 23:15:32 +02:00
parent 417d238bba
commit d1aa1ac963
5 changed files with 47 additions and 44 deletions

32
Cargo.lock generated
View file

@ -34,6 +34,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "aho-corasick"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
dependencies = [
"memchr",
]
[[package]]
name = "aliasable"
version = "0.1.3"
@ -569,7 +578,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdaa01904c12a8989dbfa110b41ef27efc432ac9934f691b9732f01cb64dc01"
dependencies = [
"aho-corasick",
"aho-corasick 0.7.19",
"byteorder",
"cpp_common",
"lazy_static",
@ -1145,6 +1154,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "humantime_to_duration"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d564881e1f668089d5653740167844f6ca8af54cd56bd6951f3dca85ba354fc"
dependencies = [
"regex",
"time",
]
[[package]]
name = "iana-time-zone"
version = "0.1.53"
@ -1880,11 +1899,11 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f"
[[package]]
name = "regex"
version = "1.7.3"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
dependencies = [
"aho-corasick",
"aho-corasick 1.0.1",
"memchr",
"regex-syntax",
]
@ -1897,9 +1916,9 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.29"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]]
name = "rlimit"
@ -3213,6 +3232,7 @@ version = "0.0.18"
dependencies = [
"clap",
"filetime",
"humantime_to_duration",
"time",
"uucore",
"windows-sys 0.45.0",

View file

@ -1,7 +1,7 @@
# coreutils (uutils)
# * see the repository LICENSE, README, and CONTRIBUTING files for more information
# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen
# spell-checker:ignore (libs) libselinux gethostid procfs bigdecimal kqueue fundu mangen humantime
[package]
name = "coreutils"
@ -286,6 +286,7 @@ fundu = "0.5.0"
gcd = "2.3"
glob = "0.3.1"
half = "2.2"
humantime_to_duration = "0.1.2"
indicatif = "0.17"
is-terminal = "0.4.6"
itertools = "0.10.5"

View file

@ -1,3 +1,4 @@
# spell-checker:ignore humantime
[package]
name = "uu_touch"
version = "0.0.18"
@ -17,6 +18,7 @@ path = "src/touch.rs"
[dependencies]
filetime = { workspace=true }
clap = { workspace=true }
humantime_to_duration = { workspace=true }
time = { workspace=true, features = ["parsing", "formatting", "local-offset", "macros"] }
uucore = { workspace=true, features=["libc"] }

View file

@ -6,7 +6,7 @@
// For the full copyright and license information, please view the LICENSE file
// that was distributed with this source code.
// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond
// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS subsecond humantime
use clap::builder::ValueParser;
use clap::{crate_version, Arg, ArgAction, ArgGroup, Command};
@ -83,7 +83,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
) {
(Some(reference), Some(date)) => {
let (atime, mtime) = stat(Path::new(reference), !matches.get_flag(options::NO_DEREF))?;
if let Some(offset) = parse_relative_time(date) {
if let Ok(offset) = humantime_to_duration::from_str(date) {
let mut seconds = offset.whole_seconds();
let mut nanos = offset.subsec_nanoseconds();
if nanos < 0 {
@ -428,7 +428,7 @@ fn parse_date(s: &str) -> UResult<FileTime> {
}
}
if let Some(duration) = parse_relative_time(s) {
if let Ok(duration) = humantime_to_duration::from_str(s) {
let now_local = time::OffsetDateTime::now_local().unwrap();
let diff = now_local.checked_add(duration).unwrap();
return Ok(local_dt_to_filetime(diff));
@ -437,39 +437,6 @@ fn parse_date(s: &str) -> UResult<FileTime> {
Err(USimpleError::new(1, format!("Unable to parse date: {s}")))
}
fn parse_relative_time(s: &str) -> Option<Duration> {
// Relative time, like "-1 hour" or "+3 days".
//
// TODO Add support for "year" and "month".
// TODO Add support for times without spaces like "-1hour".
let tokens: Vec<&str> = s.split_whitespace().collect();
match &tokens[..] {
[num_str, "fortnight" | "fortnights"] => num_str
.parse::<i64>()
.ok()
.map(|n| time::Duration::weeks(2 * n)),
["fortnight" | "fortnights"] => Some(time::Duration::weeks(2)),
[num_str, "week" | "weeks"] => num_str.parse::<i64>().ok().map(time::Duration::weeks),
["week" | "weeks"] => Some(time::Duration::weeks(1)),
[num_str, "day" | "days"] => num_str.parse::<i64>().ok().map(time::Duration::days),
["day" | "days"] => Some(time::Duration::days(1)),
[num_str, "hour" | "hours"] => num_str.parse::<i64>().ok().map(time::Duration::hours),
["hour" | "hours"] => Some(time::Duration::hours(1)),
[num_str, "minute" | "minutes" | "min" | "mins"] => {
num_str.parse::<i64>().ok().map(time::Duration::minutes)
}
["minute" | "minutes" | "min" | "mins"] => Some(time::Duration::minutes(1)),
[num_str, "second" | "seconds" | "sec" | "secs"] => {
num_str.parse::<i64>().ok().map(time::Duration::seconds)
}
["second" | "seconds" | "sec" | "secs"] => Some(time::Duration::seconds(1)),
["now" | "today"] => Some(time::Duration::ZERO),
["yesterday"] => Some(time::Duration::days(-1)),
["tomorrow"] => Some(time::Duration::days(1)),
_ => None,
}
}
fn parse_timestamp(s: &str) -> UResult<FileTime> {
// TODO: handle error
let now = time::OffsetDateTime::now_utc();

View file

@ -608,7 +608,15 @@ fn test_touch_set_date_relative_smoke() {
// > (equivalent to day), the string yesterday is worth one day
// > in the past (equivalent to day ago).
//
let times = ["yesterday", "tomorrow", "now"];
let times = [
"yesterday",
"tomorrow",
"now",
"2 seconds",
"2 years 1 week",
"2 days ago",
"2 months and 1 second",
];
for time in times {
let (at, mut ucmd) = at_and_ucmd!();
at.touch("f");
@ -617,6 +625,11 @@ fn test_touch_set_date_relative_smoke() {
.no_stderr()
.no_stdout();
}
let (at, mut ucmd) = at_and_ucmd!();
at.touch("f");
ucmd.args(&["-d", "a", "f"])
.fails()
.stderr_contains("touch: Unable to parse date");
}
#[test]