3 Commits

Author SHA1 Message Date
Sylvestre Ledru 29e64c3cda version 0.2.0 2023-05-11 17:20:24 +02:00
Sylvestre Ledru db00d0686f add a new from_str_at_date(date, string) function (#2)
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
2023-05-11 17:16:02 +02:00
Sylvestre Ledru 1f0eae3536 add the README 2023-04-25 09:00:51 +02:00
5 changed files with 111 additions and 11 deletions
Generated
+1 -1
View File
@@ -13,7 +13,7 @@ dependencies = [
[[package]]
name = "humantime_to_duration"
version = "0.1.2"
version = "0.1.4"
dependencies = [
"regex",
"time",
+2 -1
View File
@@ -1,10 +1,11 @@
[package]
name = "humantime_to_duration"
description = " parsing human-readable relative time strings and converting them to a Duration"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/uutils/humantime_to_duration"
readme = "README.md"
[dependencies]
regex = "1.7"
+12 -4
View File
@@ -11,6 +11,7 @@ A Rust crate for parsing human-readable relative time strings and converting the
- Parses a variety of human-readable time formats.
- Supports positive and negative durations.
- Allows for chaining time units (e.g., "1 hour 2 minutes" or "2 days and 2 hours").
- Calculate durations relative to a specified date.
## Usage
@@ -21,18 +22,25 @@ Add this to your `Cargo.toml`:
humantime_to_duration = "0.1.1"
```
Then, import the crate and use the from_str function:
Then, import the crate and use the `from_str` and `from_str_at_date` functions:
```
use humantime_to_duration::from_str;
use humantime_to_duration::{from_str, from_str_at_date};
use time::Duration;
let duration = from_str("+3 days");
assert_eq!(duration.unwrap(), Duration::days(3));
let today = OffsetDateTime::now_utc().date();
let yesterday = today - Duration::days(1);
assert_eq!(
from_str_at_date(yesterday, "2 days").unwrap(),
Duration::days(1)
);
```
### Supported Formats
The `from_str` function supports the following formats for relative time:
The `from_str` and `from_str_at_date` functions support the following formats for relative time:
- `num` `unit` (e.g., "-1 hour", "+3 days")
- `unit` (e.g., "hour", "day")
@@ -47,7 +55,7 @@ The `from_str` function supports the following formats for relative time:
## Return Values
The `from_str` function returns:
The `from_str` and `from_str_at_date` functions return:
- `Ok(Duration)` - If the input string can be parsed as a relative time
- `Err(ParseDurationError)` - If the input string cannot be parsed as a relative time
+67 -3
View File
@@ -4,7 +4,7 @@
use regex::{Error as RegexError, Regex};
use std::error::Error;
use std::fmt::{self, Display};
use time::Duration;
use time::{Date, Duration, OffsetDateTime};
#[derive(Debug)]
pub enum ParseDurationError {
@@ -77,6 +77,17 @@ impl From<RegexError> for ParseDurationError {
///
/// This function will return `Err(ParseDurationError::InvalidInput)` if the input string
/// cannot be parsed as a relative time.
///
/// # Examples
///
/// ```
/// use time::Duration;
/// use humantime_to_duration::{from_str, ParseDurationError};
///
/// assert_eq!(from_str("1 hour, 30 minutes").unwrap(), Duration::minutes(90));
/// assert_eq!(from_str("tomorrow").unwrap(), Duration::days(1));
/// assert!(matches!(from_str("invalid"), Err(ParseDurationError::InvalidInput)));
/// ```
pub fn from_str(s: &str) -> Result<Duration, ParseDurationError> {
let time_pattern: Regex = Regex::new(
r"(?x)
@@ -153,12 +164,39 @@ pub fn from_str(s: &str) -> Result<Duration, ParseDurationError> {
}
}
/// Parses a duration string and returns a `Duration` instance, with the duration
/// calculated from the specified date.
///
/// # Arguments
///
/// * `date` - A `Date` instance representing the base date for the calculation
/// * `s` - A string slice representing the relative time.
///
/// # Examples
///
/// ```
/// use time::{Date, Duration, OffsetDateTime};
/// use humantime_to_duration::{from_str_at_date, ParseDurationError};
/// let today = OffsetDateTime::now_utc().date();
/// let yesterday = today - Duration::days(1);
/// assert_eq!(
/// from_str_at_date(yesterday, "2 days").unwrap(),
/// Duration::days(1) // 1 day from the specified date + 1 day from the input string
/// );
/// ```
pub fn from_str_at_date(date: Date, s: &str) -> Result<Duration, ParseDurationError> {
let time_now = OffsetDateTime::now_utc().date();
let date_duration = date - time_now;
Ok(from_str(s)? + date_duration)
}
#[cfg(test)]
mod tests {
use super::from_str;
use super::ParseDurationError;
use time::Duration;
use super::{from_str, from_str_at_date};
use time::{Date, Duration, Month, OffsetDateTime};
#[test]
fn test_years() {
@@ -300,4 +338,30 @@ mod tests {
_ => assert!(false),
}*/
}
#[test]
fn test_from_str_at_date() {
let date = Date::from_calendar_date(2014, Month::September, 5).unwrap();
let now = OffsetDateTime::now_utc().date();
let days_diff = (date - now).whole_days();
assert_eq!(
from_str_at_date(date, "1 day").unwrap(),
Duration::days(days_diff + 1)
);
assert_eq!(
from_str_at_date(date, "2 hours").unwrap(),
Duration::days(days_diff) + Duration::hours(2)
);
}
#[test]
fn test_invalid_input_at_date() {
let date = Date::from_calendar_date(2014, Month::September, 5).unwrap();
assert!(matches!(
from_str_at_date(date, "invalid"),
Err(ParseDurationError::InvalidInput)
));
}
}
+29 -2
View File
@@ -1,5 +1,5 @@
use humantime_to_duration::{from_str, ParseDurationError};
use time::Duration;
use humantime_to_duration::{from_str, from_str_at_date, ParseDurationError};
use time::{Duration, OffsetDateTime};
#[test]
fn test_invalid_input() {
@@ -135,3 +135,30 @@ fn test_display_should_fail() {
"Invalid input string: cannot be parsed as a relative time"
);
}
#[test]
fn test_from_str_at_date_day() {
let today = OffsetDateTime::now_utc().date();
let yesterday = today - Duration::days(1);
assert_eq!(
from_str_at_date(yesterday, "2 days").unwrap(),
Duration::days(1)
);
}
#[test]
fn test_invalid_input_at_date() {
let today = OffsetDateTime::now_utc().date();
let result = from_str_at_date(today, "foobar");
println!("{result:?}");
match result {
Err(ParseDurationError::InvalidInput) => assert!(true),
_ => assert!(false),
}
let result = from_str_at_date(today, "invalid 1r");
match result {
Err(ParseDurationError::InvalidInput) => assert!(true),
_ => assert!(false),
}
}