Skip to content

Commit

Permalink
Allow more time specifications for reminder
Browse files Browse the repository at this point in the history
  • Loading branch information
kekonn committed Dec 3, 2024
1 parent d1a16b9 commit 2902b02
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 12 deletions.
54 changes: 52 additions & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ thiserror = "2"
clap = { version = "4", features = ["derive", "env"] }
reqwest = { version = "0.12", features = ["stream", "rustls-tls"]}
tokio-stream = "0.1"
rstest = "0.23"

fercord_common = { path = "./fercord_common", version = "0.1"}
fercord_storage = { path = "./fercord_storage", version = "0.3"}
Expand All @@ -46,7 +47,6 @@ features = ["rt-multi-thread", "time"]
version = "1"
features = ["backtrace"]


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
opt-level = "s"
Expand Down
3 changes: 3 additions & 0 deletions fercord_bot/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

## [Unreleased] - ReleaseDate

### Added
- feat: `/reminder` not also accepts `[day|tomorrow] at [hour][am|pm]` inputs.

## [0.3.5] - 2024-12-02
- chore: Update dependencies

Expand Down
6 changes: 3 additions & 3 deletions fercord_bot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ tracing-subscriber = {version = "0.3", features = ["default", "env-filter"]}
chrono = { workspace = true }
chrono-tz = { workspace = true }
interim = { workspace = true }
reqwest = { workspace = true }
uuid = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }

[dependencies.tokio-stream]
version = "0.1"

[dev-dependencies]
rstest = { workspace = true }
9 changes: 8 additions & 1 deletion fercord_bot/src/discord/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use fercord_storage::prelude::{
use crate::discord::Context;

const FROM_NOW: &str = "from now";
const AT: &str = "at";

/// Set the timezone for this server (used by time related commands).
#[poise::command(slash_command)]
Expand Down Expand Up @@ -217,7 +218,7 @@ where
span.record("cleaned_input", field::debug(&cleaned_input));
event!(Level::TRACE, ?cleaned_input, "Cleaned up raw input");

if let Ok(parsed_datetime) = parse_date_string(&cleaned_input, now.fixed_offset(), Dialect::Us)
if let Ok(parsed_datetime) = parse_date_string(&cleaned_input, now.fixed_offset(), Dialect::Uk)
{
event!(
Level::TRACE,
Expand Down Expand Up @@ -250,6 +251,12 @@ pub(crate) fn clean_input(natural_input: String) -> String {
pre_clean.drain(now_pos..now_pos + from_now_len);
}

if let Some(at_pos) = pre_clean.find(AT) {
let at_len = AT.len();

pre_clean.drain(at_pos..at_pos + at_len);
}

pre_clean.trim().to_string()
}

Expand Down
37 changes: 32 additions & 5 deletions fercord_bot/src/discord/tests.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
use chrono::Utc;
use chrono::{Duration, NaiveTime, TimeDelta, Timelike, Utc};
use rstest::*;

use crate::discord::commands::*;

/// `"5 minutes"`
const EXPECTED: &str = "5 minutes";

#[test]
fn duration_for_dhm_from_now(days: i64, h: u32, m: u32, s: u32) -> TimeDelta {
let now = Utc::now();
let time = NaiveTime::from_hms_opt(h, m, s).expect("Expected valid NaiveTime");
let days_from_now = (now + Duration::days(days)).date_naive();

days_from_now.and_time(time) - now.naive_utc().with_nanosecond(0).unwrap()
}

#[rstest]
#[case("in 5 minutes", TimeDelta::minutes(5))]
#[case("tomorrow at 8am", duration_for_dhm_from_now(1.into(), 8, 0, 0))]
#[case("in 1 hour", TimeDelta::hours(1))]
fn check_parser(#[case] input: &str, #[case] expected: TimeDelta) {
// Arrange
let now = Utc::now().with_nanosecond(0).unwrap();

// Act
let parsed = parse_human_time(input, Utc, Some(now));

// Assert
assert!(parsed.is_ok(), "Could not parse '{input}' to a DateTime");
let unwrapped = parsed.unwrap();
assert!(unwrapped > now, "Parsed time appears to be in the past: unwrapped={unwrapped} now={now}");
assert_eq!(expected, (unwrapped - now), "Parsed time ({unwrapped}) does not match the expected time ({expected})");
}

#[rstest]
fn parsed_moment_is_future() {
// Arrange
let input = "in 5 minutes";
Expand All @@ -26,7 +53,7 @@ fn parsed_moment_is_future() {
assert_eq!(difference.num_minutes(), 5);
}

#[test]
#[rstest]
fn clean_input_cleans_in_syntax() {
let input = "in 5 minutes";

Expand All @@ -35,7 +62,7 @@ fn clean_input_cleans_in_syntax() {
assert_eq!(EXPECTED, result);
}

#[test]
#[rstest]
fn clean_input_cleans_from_syntax() {
let input = "5 minutes from now";

Expand All @@ -44,7 +71,7 @@ fn clean_input_cleans_from_syntax() {
assert_eq!(EXPECTED, result);
}

#[test]
#[rstest]
fn clean_input_cleans_combined_syntax() {
let input = "in 5 minutes from now";

Expand Down

0 comments on commit 2902b02

Please sign in to comment.