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
use crate::client::{Client, RawResp};
use async_trait::async_trait;
use std::convert::From;
use std::str::FromStr;
pub(crate) fn is_event(resp: &RawResp) -> Option<String> {
for name in vec![
"notifycliententerview",
"notifyclientleftview",
"notifyserveredited",
"notifychanneldescriptionchanged",
"notifychannelpasswordchanged",
"notifychannelmoved",
"notifychanneledited",
"notifychannelcreated",
"notifychanneldeleted",
"notifyclientmoved",
"notifytextmessage",
"notifytokenused",
] {
if resp.items[0].contains_key(name) {
return Some(name.to_owned());
}
}
None
}
pub(crate) async fn dispatch_event(c: Client, resp: RawResp, event: &str) {
let c2 = c.clone();
let handler = c2.inner.read().unwrap().handler.clone();
match event {
"notifycliententerview" => handler.cliententerview(c, resp),
"notifyclientleftview" => handler.clientleftview(c, resp),
"notifyserveredited" => handler.serveredited(c, resp),
"notifychanneldescriptionchanged" => handler.channeldescriptionchanged(c, resp),
"notifychannelpasswordchanged" => handler.channelpasswordchanged(c, resp),
"notifychannelmoved" => handler.channelmoved(c, resp),
"notifychanneledited" => handler.channeledited(c, resp),
"notifychannelcreated" => handler.channelcreated(c, resp),
"notifychanneldeleted" => handler.channeldeleted(c, resp),
"notifyclientmoved" => handler.clientmoved(c, resp),
"notifytextmessage" => handler.textmessage(c, resp.into()),
"notifytokenused" => handler.tokenused(c, resp),
_ => unreachable!(),
}
.await;
}
#[async_trait]
pub trait EventHandler: Send + Sync {
async fn cliententerview(&self, _client: Client, _event: RawResp) {}
async fn clientleftview(&self, _client: Client, _event: RawResp) {}
async fn serveredited(&self, _client: Client, _event: RawResp) {}
async fn channeldescriptionchanged(&self, _client: Client, _event: RawResp) {}
async fn channelpasswordchanged(&self, _client: Client, _event: RawResp) {}
async fn channelmoved(&self, _client: Client, _event: RawResp) {}
async fn channeledited(&self, _client: Client, _event: RawResp) {}
async fn channelcreated(&self, _client: Client, _event: RawResp) {}
async fn channeldeleted(&self, _client: Client, _event: RawResp) {}
async fn clientmoved(&self, _client: Client, _event: RawResp) {}
async fn textmessage(&self, _client: Client, _event: TextMessage) {}
async fn tokenused(&self, _client: Client, _event: RawResp) {}
}
#[derive(Clone, Debug)]
pub struct TextMessage {
pub targetmode: usize,
pub msg: String,
pub target: usize,
pub invokerid: usize,
pub invokername: String,
pub invokeruid: String,
}
impl From<RawResp> for TextMessage {
fn from(raw: RawResp) -> TextMessage {
TextMessage {
targetmode: get_field(&raw, "targetmod"),
msg: get_field(&raw, "msg"),
target: get_field(&raw, "target"),
invokerid: get_field(&raw, "invokerid"),
invokername: get_field(&raw, "invokername"),
invokeruid: get_field(&raw, "invokeruid"),
}
}
}
pub(crate) struct Handler;
impl EventHandler for Handler {}
fn get_field<T>(raw: &RawResp, name: &str) -> T
where
T: FromStr + Default,
{
match raw.items.get(0) {
Some(val) => match val.get(name) {
Some(val) => match val {
Some(val) => match T::from_str(&val) {
Ok(val) => val,
Err(_) => T::default(),
},
None => T::default(),
},
None => T::default(),
},
None => T::default(),
}
}