1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use super::config;
use super::irc_msgs::OwningMsgPrefix;
use super::BotCommand;
use super::ErrorKind;
use super::MsgPrefix;
use super::Result;
use super::Server;
use super::ServerId;
use super::State;
use rand::StdRng;
use std::borrow::Cow;
use std::path::Path;
use std::sync::MutexGuard;
use std::sync::RwLockReadGuard;
impl State {
pub fn nick(&self, server_id: ServerId) -> Result<String> {
self.read_msg_prefix(server_id)?
.parse()
.nick
.ok_or(ErrorKind::NicknameUnknown.into())
.map(ToOwned::to_owned)
}
pub fn module_data_path(&self) -> Result<&Path> {
Ok(self.module_data_path.as_ref())
}
pub fn command(&self, name: &str) -> Result<Option<&BotCommand>> {
Ok(self.commands.get(name))
}
pub fn command_names(&self) -> Result<Vec<Cow<'static, str>>> {
Ok(self.commands.keys().cloned().collect())
}
pub fn have_admin(
&self,
MsgPrefix {
nick: nick_1,
user: user_1,
host: host_1,
}: MsgPrefix,
) -> Result<bool> {
Ok(self.config.admins.iter().any(
|&config::Admin {
nick: ref nick_2,
user: ref user_2,
host: ref host_2,
}| {
check_admin_cred(nick_1, nick_2) && check_admin_cred(user_1, user_2)
&& check_admin_cred(host_1, host_2)
},
))
}
pub(super) fn read_msg_prefix(
&self,
_server_id: ServerId,
) -> Result<RwLockReadGuard<OwningMsgPrefix>> {
self.msg_prefix
.read()
.map_err(|_| ErrorKind::LockPoisoned("stored message prefix".into()).into())
}
pub(super) fn read_server(
&self,
server_id: ServerId,
) -> Result<Option<RwLockReadGuard<Server>>> {
match self.servers.get(&server_id) {
Some(lock) => match lock.read() {
Ok(guard) => Ok(Some(guard)),
Err(_) => Err(ErrorKind::LockPoisoned(
format!("server {}", server_id.uuid.hyphenated()).into(),
).into()),
},
None => Ok(None),
}
}
pub fn rng(&self) -> Result<MutexGuard<StdRng>> {
self.rng.lock().map_err(|_| {
ErrorKind::LockPoisoned("the central random number generator".into()).into()
})
}
pub(super) fn server_socket_addr_dbg_string(&self, server_id: ServerId) -> String {
let uuid = server_id.uuid.hyphenated();
match self.read_server(server_id) {
Ok(Some(s)) => s.socket_addr_string.clone(),
Ok(None) => format!("<unknown server {} (not found)>", uuid),
Err(e) => format!("<unknown server {} ({})>", uuid, e),
}
}
}
fn check_admin_cred(candidate: Option<&str>, control: &Option<String>) -> bool {
match (candidate, control) {
(Some(cdt), &Some(ref ctl)) => {
cdt == ctl
}
(_, &None) => {
true
}
(None, &Some(_)) => {
false
}
}
}