traq_bot_http/payloads/system.rs
1//! システム関連のイベントペイロード
2//! ## types
3//! - [`PingPayload`](PingPayload)
4//! - [`JoinedPayload`](JoinedPayload)
5//! - [`LeftPayload`](LeftPayload)
6
7use serde::{Deserialize, Serialize};
8
9use super::types::{Channel, TimeStamp};
10
11/// `PING`ペイロード
12/// - [traQの型定義](https://github.com/traPtitech/traQ/blob/d2bc98f1e0e68f4acc371eb78e6a49a167446761/service/bot/event/payload/ev_ping.go#L5-L8)
13/// - [traQ-bot-consoleのリファレンス](https://github.com/traPtitech/traQ-bot-console/blob/dev/src/docs/bot/events/system.md#ping)
14///
15/// ## Example
16/// ```
17/// # fn main() -> Result<(), serde_json::Error> {
18/// use traq_bot_http::payloads::PingPayload;
19/// let payload = r##"{
20/// "eventTime": "2019-05-07T04:50:48.582586882Z"
21/// }"##;
22/// let payload: PingPayload = payload.parse()?;
23/// println!("{payload}");
24/// # Ok(())
25/// # }
26/// ```
27#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
28#[serde(rename_all = "camelCase")]
29pub struct PingPayload {
30 #[serde(with = "crate::payloads::serde::timestamp")]
31 pub event_time: TimeStamp,
32}
33
34/// `JOINED`ペイロード
35/// - [traQの型定義](https://github.com/traPtitech/traQ/blob/d2bc98f1e0e68f4acc371eb78e6a49a167446761/service/bot/event/payload/ev_joined.go#L9-L13)
36/// - [traQ-bot-consoleのリファレンス](https://github.com/traPtitech/traQ-bot-console/blob/dev/src/docs/bot/events/system.md#joined)
37///
38/// ## Example
39/// ```
40/// # fn main() -> Result<(), serde_json::Error> {
41/// use traq_bot_http::payloads::JoinedPayload;
42/// let payload = r##"{
43/// "eventTime": "2019-05-08T13:49:13.769110201Z",
44/// "channel": {
45/// "id": "f86c925c-3002-4ba5-939a-c92344e534f9",
46/// "name": "po",
47/// "path": "#a/po",
48/// "parentId": "ea452867-553b-4808-a14f-a47ee0009ee6",
49/// "creator": {
50/// "id": "dfdff0c9-5de0-46ee-9721-2525e8bb3d45",
51/// "name": "takashi_trap",
52/// "displayName": "寺田 健二",
53/// "iconId": "2bc06cda-bdb9-4a68-8000-62f907f36a92",
54/// "bot": false
55/// },
56/// "createdAt": "2018-04-25T12:22:02Z",
57/// "updatedAt": "2018-04-25T12:22:02Z"
58/// }
59/// }"##;
60/// let payload: JoinedPayload = payload.parse()?;
61/// println!("{payload}");
62/// # Ok(())
63/// # }
64/// ```
65#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
66#[serde(rename_all = "camelCase")]
67pub struct JoinedPayload {
68 #[serde(with = "crate::payloads::serde::timestamp")]
69 pub event_time: TimeStamp,
70 pub channel: Channel,
71}
72
73impl From<LeftPayload> for JoinedPayload {
74 fn from(payload: LeftPayload) -> Self {
75 let LeftPayload {
76 event_time,
77 channel,
78 } = payload;
79 Self {
80 event_time,
81 channel,
82 }
83 }
84}
85
86/// `LEFT`ペイロード
87/// - [traQの型定義](https://github.com/traPtitech/traQ/blob/d2bc98f1e0e68f4acc371eb78e6a49a167446761/service/bot/event/payload/ev_left.go#L9-L13)
88/// - [traQ-bot-consoleのリファレンス](https://github.com/traPtitech/traQ-bot-console/blob/dev/src/docs/bot/events/system.md#left)
89///
90/// ## Example
91/// ```
92/// # fn main() -> Result<(), serde_json::Error> {
93/// use traq_bot_http::payloads::LeftPayload;
94/// let payload = r##"{
95/// "eventTime": "2019-05-08T13:49:16.497848449Z",
96/// "channel": {
97/// "id": "f86c925c-3002-4ba5-939a-c92344e534f9",
98/// "name": "po",
99/// "path": "#a/po",
100/// "parentId": "ea452867-553b-4808-a14f-a47ee0009ee6",
101/// "creator": {
102/// "id": "dfdff0c9-5de0-46ee-9721-2525e8bb3d45",
103/// "name": "takashi_trap",
104/// "displayName": "寺田 健二",
105/// "iconId": "2bc06cda-bdb9-4a68-8000-62f907f36a92",
106/// "bot": false
107/// },
108/// "createdAt": "2018-04-25T12:22:02Z",
109/// "updatedAt": "2018-04-25T12:22:02Z"
110/// }
111/// }"##;
112/// let payload: LeftPayload = payload.parse()?;
113/// println!("{payload}");
114/// # Ok(())
115/// # }
116/// ```
117#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
118#[serde(rename_all = "camelCase")]
119pub struct LeftPayload {
120 #[serde(with = "crate::payloads::serde::timestamp")]
121 pub event_time: TimeStamp,
122 pub channel: Channel,
123}
124
125impl From<JoinedPayload> for LeftPayload {
126 fn from(payload: JoinedPayload) -> Self {
127 let JoinedPayload {
128 event_time,
129 channel,
130 } = payload;
131 Self {
132 event_time,
133 channel,
134 }
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141 use crate::test_utils::{channel_a_po, timestamp};
142
143 use std::fs::read_to_string;
144
145 #[test]
146 fn ping_test() {
147 let data = read_to_string("testdata/system/ping.json").unwrap();
148 let payload: PingPayload = data.parse().unwrap();
149 let pretty_payload = serde_json::to_string_pretty(&payload).unwrap();
150 println!("{pretty_payload}");
151 println!("{payload}");
152 assert_eq!(
153 payload,
154 PingPayload {
155 event_time: timestamp("2019-05-07T04:50:48.582586882Z")
156 }
157 );
158 }
159
160 #[test]
161 fn joined_test() {
162 let data = read_to_string("testdata/system/joined.json").unwrap();
163 let payload: JoinedPayload = data.parse().unwrap();
164 let pretty_payload = serde_json::to_string_pretty(&payload).unwrap();
165 println!("{pretty_payload}");
166 println!("{payload}");
167 assert_eq!(
168 payload,
169 JoinedPayload {
170 event_time: timestamp("2019-05-08T13:49:13.769110201Z"),
171 channel: channel_a_po(),
172 }
173 );
174 }
175
176 #[test]
177 fn left_test() {
178 let data = read_to_string("testdata/system/left.json").unwrap();
179 let payload: LeftPayload = data.parse().unwrap();
180 let pretty_payload = serde_json::to_string_pretty(&payload).unwrap();
181 println!("{pretty_payload}");
182 println!("{payload}");
183 assert_eq!(
184 payload,
185 LeftPayload {
186 event_time: timestamp("2019-05-08T13:49:16.497848449Z"),
187 channel: channel_a_po(),
188 },
189 );
190 }
191}