use redis::{Client, Commands, RedisError}; use serde::{Deserialize, Serialize}; use serenity::model::prelude::*; use std::fmt; // TODO: time #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct InboxMessage { sender: UserId, content: String, recipient: String, } impl InboxMessage { pub fn parse(raw: &str, sender: UserId) -> Option { raw.strip_prefix("!message ") .and_then(|m| m.split_once(":")) .map(|(recipient, content)| InboxMessage { sender, content: content.trim().to_string(), recipient: recipient.to_string(), }) .filter(|m| m.recipient.len() < 20) } } impl fmt::Display for InboxMessage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("<@{}>: {}", self.sender.0, self.content)) } } pub struct Inbox(pub Client); impl Inbox { pub fn fetch_messages(&self, recipient: &str) -> Vec { self.0 .get_connection() .and_then(|mut conn| conn.lrange(&inbox_name(recipient), 0, -1)) .map(|ss: Vec| { ss.iter() .map(|s| serde_json::from_str(s).unwrap()) .collect() }) .unwrap_or_else(|_| Vec::new()) } pub fn count_messages(&self, recipient: &str) -> usize { self.0 .get_connection() .and_then(|mut conn| conn.llen(&inbox_name(recipient))) .unwrap_or(0) } pub fn clear_messages(&self, recipient: &str) -> Result<(), RedisError> { self.0 .get_connection() .and_then(|mut conn| conn.del(&inbox_name(recipient))) } pub fn queue_message(&self, msg: &InboxMessage) -> Result { self.0 .get_connection() .and_then(|mut conn| { conn.rpush( &inbox_name(&msg.recipient), serde_json::to_string(&msg).unwrap(), ) }) .map(|_: usize| msg.recipient.clone()) .map_err(|e| { eprintln!("{:?}", e); String::from("Beim Speichern deiner Nachricht ist ein Fehler aufgetreten. Bitte sag kageru Bescheid.") }) } } fn inbox_name(name: &str) -> String { format!("{}-{}", super::APPLICATION_NAME, name.to_lowercase()) } #[cfg(test)] mod test { use super::*; #[test] fn inbox_message_conversion_test() { assert_eq!( InboxMessage::parse("!message Lana: hawwu, ich mag dich", UserId(123)), Some(InboxMessage { sender: UserId(123), content: String::from("hawwu, ich mag dich"), recipient: String::from("Lana"), }) ); assert_eq!( InboxMessage::parse("!message Ivy: hallu :3", UserId(123)), Some(InboxMessage { sender: UserId(123), content: String::from("hallu :3"), recipient: String::from("Ivy"), }) ); assert_eq!( InboxMessage::parse( "!message Flayn Gelobt seist du, oh königliche Hoheit!", UserId(123) ), None, ); assert_eq!( InboxMessage::parse( "!message Name Das hier ist ein Text, aber der Doppelpunkt ist hier -> :D", UserId(123) ), None, ); } }