HypeBot/src/reminder/mod.rs

157 lines
4.3 KiB
Rust

use crate::database::models::Event;
use crate::hypebot_config::HypeBotConfig;
use chrono::{Duration, NaiveDateTime, Utc};
use serenity::prelude::TypeMapKey;
/// Event Reminder
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Reminder {
pub event_id: i32,
pub time: NaiveDateTime,
pub reminder_id: usize,
}
/// Set of reminders for currently active events
#[derive(Debug, Clone, Default)]
pub struct Reminders {
reminders: Vec<Reminder>,
}
impl TypeMapKey for Reminders {
type Value = Reminders;
}
impl Reminders {
/// Add all the reminders for an event
pub fn add_reminders(&mut self, event: &Event, config: &HypeBotConfig) {
if let Some(event_reminders) = &config.reminders {
for (reminder_id, event_reminder) in event_reminders.iter().enumerate() {
let reminder_time = event.event_time
- chrono::Duration::minutes(event_reminder.reminder_time as i64);
if reminder_time > Utc::now().naive_utc() {
self.reminders.push(Reminder {
event_id: event.id,
time: reminder_time,
reminder_id,
});
}
}
}
}
/// Get reminders that need to be sent
pub fn get_reminders(&mut self) -> Vec<Reminder> {
let reminders: Vec<Reminder> = self
.reminders
.iter()
.filter(|r| {
let time_diff = r.time - Utc::now().naive_utc();
time_diff > Duration::seconds(-5) && time_diff < Duration::seconds(5)
})
.copied()
.collect();
self.reminders.retain(|r| !reminders.contains(r));
reminders
}
/// Removes reminders for an event
pub fn remove_reminders(&mut self, event: &Event) {
self.reminders.retain(|e| e.event_id != event.id)
}
/// Update reminders for an event
#[allow(dead_code)]
pub fn update_reminders(&mut self, event: &Event, config: &HypeBotConfig) {
self.remove_reminders(event);
self.add_reminders(event, config);
}
}
#[cfg(test)]
mod tests {
use crate::hypebot_config::{EventReminder, HypeBotConfig};
use crate::models::Event;
use crate::reminder::Reminders;
use chrono::{Duration, Utc};
fn setup() -> (Reminders, HypeBotConfig, Event) {
let r = Reminders::default();
let c = HypeBotConfig {
db_url: "".to_string(),
default_thumbnail_link: "".to_string(),
discord_key: "".to_string(),
prefix: "".to_string(),
event_channel: 0,
event_roles: vec![],
ping_roles: vec![],
event_timezone: chrono_tz::UTC,
log_path: "".to_string(),
reminders: Some(
[EventReminder {
msg: "".to_string(),
reminder_time: 5,
},
EventReminder {
msg: "".to_string(),
reminder_time: 1,
}]
.to_vec(),
),
};
let e = Event {
id: 0,
event_name: "".to_string(),
event_desc: "".to_string(),
event_loc: "".to_string(),
organizer: "".to_string(),
event_time: Utc::now().naive_utc() + Duration::minutes(5) + Duration::seconds(5),
message_id: "".to_string(),
thumbnail_link: "".to_string(),
reminder_sent: 0,
};
(r, c, e)
}
#[test]
fn test_add_reminders() {
let (mut r, c, e) = setup();
r.add_reminders(&e, &c);
assert_eq!(r.reminders.len(), c.reminders.unwrap().len());
}
#[test]
fn test_get_reminders() {
let (mut r, c, e) = setup();
r.add_reminders(&e, &c);
assert_eq!(r.get_reminders().len(), 1);
assert_eq!(r.reminders.len(), c.reminders.unwrap().len()-1);
}
#[test]
fn test_remove_reminders() {
let (mut r, c, e) = setup();
r.add_reminders(&e, &c);
r.remove_reminders(&e);
assert_eq!(r.reminders.len(), 0);
}
#[test]
fn test_update_reminders() {
let (mut r, c, e) = setup();
r.add_reminders(&e, &c);
r.update_reminders(&e, &c);
assert_eq!(r.get_reminders().len(), 1);
}
}