1use super::ServerId;
2
3#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4pub struct MsgDest<'a> {
5 pub server_id: ServerId,
6 pub target: &'a str,
7}
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct MsgPrefix<'a> {
11 pub nick: Option<&'a str>,
12 pub user: Option<&'a str>,
13 pub host: Option<&'a str>,
14}
15
16#[derive(Debug)]
17pub struct MsgMetadata<'a> {
18 pub dest: MsgDest<'a>,
19 pub prefix: MsgPrefix<'a>,
20}
21
22#[derive(Debug)]
23pub struct OwningMsgPrefix {
24 backing: String,
25}
26
27#[cfg(feature = "pircolate")]
28fn prefix_from_pircolate<'a>(
29 pirc_pfx: Option<(&'a str, Option<&'a str>, Option<&'a str>)>,
30) -> MsgPrefix<'a> {
31 match pirc_pfx {
32 Some((nick, user, host)) => MsgPrefix {
33 nick: Some(nick),
34 user: user,
35 host: host,
36 },
37 None => MsgPrefix {
38 nick: None,
39 user: None,
40 host: None,
41 },
42 }
43}
44
45pub(super) fn is_msg_to_nick(target: &str, msg: &str, nick: &str) -> bool {
46 target == nick || msg == nick || (msg.starts_with(nick) && (msg.find(|c: char| {
47 [':', ','].contains(&c)
48 }) == Some(nick.len())))
49}
50
51pub(super) fn parse_msg_to_nick<'msg>(
52 text: &'msg str,
53 target: &str,
54 nick: &str,
55) -> Option<&'msg str> {
56 if is_msg_to_nick(target, text, nick) {
57 Some(
58 text.trim_left_matches(nick)
59 .trim_left_matches(|c: char| [':', ','].contains(&c))
60 .trim(),
61 )
62 } else {
63 None
64 }
65}
66
67pub(super) fn parse_prefix(prefix: &str) -> MsgPrefix {
68 let mut iter = prefix.rsplitn(2, '@');
69 let host = iter.next();
70 let mut iter = iter.next().unwrap_or("").splitn(2, '!');
71 let nick = iter.next();
72 let user = iter.next();
73 MsgPrefix {
74 nick: nick,
75 user: user,
76 host: host,
77 }
78}
79
80impl<'a> MsgPrefix<'a> {
81 pub fn len(&self) -> usize {
83 fn component_len(component: Option<&str>) -> usize {
84 component.map(|s| s.len()).unwrap_or(0)
85 }
86
87 component_len(self.nick) + component_len(self.user) + component_len(self.host) + 2
88 }
89
90 pub fn to_owning(&self) -> OwningMsgPrefix {
95 OwningMsgPrefix::from_string(format!(
96 "{}!{}@{}",
97 self.nick.unwrap_or(""),
98 self.user.unwrap_or(""),
99 self.host.unwrap_or("")
100 ))
101 }
102}
103
104impl OwningMsgPrefix {
105 pub fn from_string(prefix: String) -> Self {
106 OwningMsgPrefix { backing: prefix }
107 }
108
109 pub fn parse<'a>(&'a self) -> MsgPrefix<'a> {
110 parse_prefix(&self.backing)
111 }
112
113 pub fn len(&self) -> usize {
115 self.backing.len()
116 }
117
118 pub(super) fn update_from(&mut self, new: &MsgPrefix) {
121 fn updated<'old, 'new>(old: Option<&'old str>, new: Option<&'new str>) -> &'old str
122 where
123 'new: 'old,
124 {
125 match (old, new) {
126 (_, Some(s)) => s,
127 (Some(s), None) => s,
128 (None, None) => "",
129 }
130 }
131
132 self.backing = {
133 let old = self.parse();
134 format!(
135 "{}!{}@{}",
136 updated(old.nick, new.nick),
137 updated(old.user, new.user),
138 updated(old.host, new.host)
139 )
140 }
141 }
142}