pub trait FromMessage<'a>: Sized {
fn from_str(s: &'a str) -> Result<Self, crate::DeError> {
let msg = crate::parse(s)?;
Self::from_message(&msg)
}
fn from_message(msg: &crate::Message<'a>) -> Result<Self, crate::DeError>;
}
#[cfg(test)]
mod tests {
use crate::{de::FromMessage, DeError};
#[derive(Debug)]
struct TestMessage<'a> {
aaa: Option<&'a str>,
ccc: bool,
nick: &'a str,
message: &'a str,
}
impl<'a> FromMessage<'a> for TestMessage<'a> {
fn from_message(msg: &crate::Message<'a>) -> Result<Self, DeError> {
let command = msg.command();
if !command.is_privmsg() {
return Err(DeError::command_mismatch("PRIVMSG", command.as_str()));
}
let tags = msg.tags().ok_or(DeError::tags_component_not_found())?;
let aaa = tags.get("aaa").map(|e| e.as_str());
let ccc = tags.get_flag("ccc");
let source = msg.source().ok_or(DeError::source_component_not_found())?;
let nick = source.name;
let params = msg.params();
let message = params.trailing;
Ok(Self {
aaa,
ccc,
nick,
message: message.as_str(),
})
}
}
#[test]
pub fn from_message_with_tags() {
let input = "@aaa=bbb;ccc;example.com/ddd=eee;+fff=;ggg=hello\\sworld :nick!user@host.com PRIVMSG #channel :Hello World!";
let test_message: TestMessage = crate::from_str(input).unwrap();
assert_eq!(Some("bbb"), test_message.aaa);
assert!(test_message.ccc);
assert_eq!("nick", test_message.nick);
assert_eq!("Hello World!", test_message.message);
}
#[test]
pub fn from_str_method() {
let input = "@aaa=bbb;ccc;example.com/ddd=eee;+fff=;ggg=hello\\sworld :nick!user@host.com PRIVMSG #channel :Hello World!";
let test_message = TestMessage::from_str(input).unwrap();
assert_eq!(Some("bbb"), test_message.aaa);
assert!(test_message.ccc);
assert_eq!("nick", test_message.nick);
assert_eq!("Hello World!", test_message.message);
}
#[test]
fn invalid_command_error() {
let input = ":nick JOIN #channel";
let error = TestMessage::from_str(input).expect_err("Expected invalid command error");
assert!(error.is_command_mismatch());
}
#[test]
fn missing_source_error() {
let input = "@aaa=bbb PRIVMSG #channel :Hello";
let error = TestMessage::from_str(input).expect_err("Expected missing source error");
assert!(error.is_source_component_not_found());
}
}