2021-05-03 21:50:44 +02:00
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 ( ) )
2021-11-25 22:29:25 +01:00
. map_err ( | e | {
2021-05-03 21:50:44 +02:00
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 ,
) ;
}
}