120 lines
3.5 KiB
Rust
120 lines
3.5 KiB
Rust
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<Self> {
|
|
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<InboxMessage> {
|
|
self.0
|
|
.get_connection()
|
|
.and_then(|mut conn| conn.lrange(&inbox_name(recipient), 0, -1))
|
|
.map(|ss: Vec<String>| {
|
|
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<String, String> {
|
|
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,
|
|
);
|
|
}
|
|
}
|