use std::collections::HashMap;
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Message<'a> {
tags: HashMap<&'a str, &'a str>,
prefix_name: Option<&'a str>,
prefix_user: Option<&'a str>,
prefix_host: Option<&'a str>,
command: &'a str,
params: Vec<&'a str>,
trailing: Option<&'a str>,
}
impl<'a> Message<'a> {
pub fn new(command: &'a str) -> Self {
Message {
tags: HashMap::new(),
prefix_name: None,
prefix_user: None,
prefix_host: None,
command: "",
params: Vec::new(),
trailing: None,
}
.command(command)
}
pub fn command(mut self, cmd: &'a str) -> Message<'a> {
if cmd.is_empty() {
panic!("tried to set empty command");
}
self.command = cmd;
self
}
pub fn tag(mut self, key: &'a str, value: &'a str) -> Message<'a> {
if key.is_empty() {
panic!("tried to set tag with empty key");
}
self.tags.insert(key, value);
self
}
pub fn prefix(
mut self,
name: &'a str,
user: Option<&'a str>,
host: Option<&'a str>,
) -> Message<'a> {
if name.is_empty() {
panic!("tried to set empty prefix name");
}
if user.is_some() && user.unwrap().is_empty() {
panic!("tried to set empty prefix user");
}
if host.is_some() && host.unwrap().is_empty() {
panic!("tried to set empty prefix host");
}
if user.is_some() && host.is_none() {
panic!("tried to set prefix user without host");
}
self.prefix_name = Some(name);
self.prefix_user = user;
self.prefix_host = host;
self
}
pub fn param(mut self, param: &'a str) -> Message<'a> {
if param.is_empty() {
panic!("tried to add empty param");
}
self.params.push(param);
self
}
pub fn set_param(mut self, index: usize, param: &'a str) -> Message<'a> {
if param.is_empty() {
panic!("tried to set empty param");
}
if index >= self.params.len() {
self.params.push(param);
}
self.params[index] = param;
self
}
pub fn remove_param(mut self, index: usize) -> Message<'a> {
if index < self.params.len() {
self.params.remove(index);
}
self
}
pub fn trailing(mut self, trailing: &'a str) -> Message<'a> {
self.trailing = Some(trailing);
self
}
pub fn build(self) -> crate::message::Message {
let mut str = String::new();
if !self.tags.is_empty() {
str.push('@');
for (key, val) in self.tags {
str.push_str(key);
str.push('=');
str.push_str(val);
str.push(';')
}
str.pop();
str.push(' ');
}
if let Some(prefix_name) = self.prefix_name {
str.push(':');
str.push_str(prefix_name);
assert!(self.prefix_user.is_none() || self.prefix_host.is_some());
if let Some(user) = self.prefix_user {
str.push('!');
str.push_str(user);
}
if let Some(host) = self.prefix_host {
str.push('@');
str.push_str(host);
}
str.push(' ')
}
str.push_str(self.command);
if !self.params.is_empty() {
str.push(' ');
str.push_str(&self.params.join(" "));
}
if let Some(trailing) = self.trailing {
str.push_str(" :");
str.push_str(trailing);
}
crate::message::Message::from(str)
}
}