1use chrono::serde::ts_seconds;
2use chrono::{DateTime, TimeZone, Utc};
3use rsb_derive::Builder;
4use rvstruct::ValueStruct;
5use serde::{Deserialize, Serialize};
6use serde_with::{serde_as, skip_serializing_none};
7use std::hash::Hash;
8use std::*;
9use url::Url;
10
11mod user;
12
13pub use user::*;
14
15mod team;
16
17pub use team::*;
18
19mod channel;
20
21pub use channel::*;
22
23mod reaction;
24
25pub use reaction::*;
26
27mod star;
28
29pub use star::*;
30
31mod bot;
32
33pub use bot::*;
34
35mod icon;
36
37pub use icon::*;
38
39mod formatters;
40
41pub use formatters::*;
42
43mod emoji;
44
45pub use emoji::*;
46
47#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
48pub struct SlackTs(pub String);
49
50impl SlackTs {
51 pub fn to_date_time_opt(&self) -> Option<DateTime<Utc>> {
52 let parts: Vec<&str> = self.value().split('.').collect();
53 if let Ok(ts_int) = parts[0].parse::<i64>() {
54 match Utc.timestamp_millis_opt(ts_int * 1000) {
55 chrono::LocalResult::None => None,
56 chrono::LocalResult::Single(result) => Some(result),
57 chrono::LocalResult::Ambiguous(first, _) => Some(first),
58 }
59 } else {
60 None
61 }
62 }
63}
64
65#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
66pub struct SlackScheduledMid(pub String);
67
68#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
69pub struct SlackTeamId(pub String);
70
71#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
72pub struct SlackEnterpriseSubteamId(pub String);
73
74#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
75pub struct SlackAppId(pub String);
76
77#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
78pub struct SlackChannelId(pub String);
79
80#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
81pub struct SlackClientMessageId(pub String);
82
83impl SlackTextFormat for SlackChannelId {
84 fn to_slack_format(&self) -> String {
85 format!("<#{}>", self.value())
86 }
87}
88
89#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
90pub struct SlackChannelType(pub String);
91
92#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
93pub struct SlackConversationId(pub String);
94
95#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
96pub struct SlackActionId(pub String);
97
98#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
99pub struct SlackActionType(pub String);
100
101#[derive(Debug, Eq, Hash, PartialEq, Clone, Serialize, Deserialize, ValueStruct)]
102pub struct SlackUserId(pub String);
103
104#[derive(Debug, Eq, Hash, PartialEq, Clone, Serialize, Deserialize, ValueStruct)]
105pub struct SlackUserGroupId(pub String);
106
107impl SlackTextFormat for SlackUserId {
108 fn to_slack_format(&self) -> String {
109 format!("<@{}>", self.value())
110 }
111}
112
113impl SlackTextFormat for SlackUserGroupId {
114 fn to_slack_format(&self) -> String {
115 format!("<!subteam^{}>", self.value())
116 }
117}
118
119#[derive(Debug, Eq, Hash, PartialEq, Clone, Serialize, Deserialize, ValueStruct)]
120pub struct SlackBotId(pub String);
121
122#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
123pub struct SlackDateTime(#[serde(with = "ts_seconds")] pub DateTime<Utc>);
124
125#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
126pub struct SlackLocale(pub String);
127
128#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
129pub struct SlackCursorId(pub String);
130
131#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
132pub struct SlackColor(pub String);
133
134#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
135pub struct SlackCallbackId(pub String);
136
137#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
138pub struct SlackTriggerId(pub String);
139
140#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
141pub struct SlackViewId(pub String);
142
143#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
144pub struct SlackCommandId(pub String);
145
146#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
147pub struct SlackClientId(pub String);
148
149#[derive(Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
150pub struct SlackClientSecret(pub String);
151
152impl fmt::Debug for SlackClientSecret {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
154 write!(f, "SlackClientSecret(len:{})", self.value().len())
155 }
156}
157
158#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
159pub struct SlackApiTokenScope(pub String);
160
161#[derive(Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
162pub struct SlackVerificationToken(pub String);
163
164impl fmt::Debug for SlackVerificationToken {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
166 write!(f, "SlackVerificationToken(len:{})", self.value().len())
167 }
168}
169
170#[derive(Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
171pub struct SlackSigningSecret(pub String);
172
173impl fmt::Debug for SlackSigningSecret {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
175 write!(f, "SlackSigningSecret(len:{})", self.value().len())
176 }
177}
178
179#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
180pub struct EmailAddress(pub String);
181
182#[serde_as]
183#[skip_serializing_none]
184#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
185pub struct SlackResponseMetadata {
186 #[serde(default)]
187 #[serde_as(as = "serde_with::NoneAsEmptyString")]
188 pub next_cursor: Option<SlackCursorId>,
189}
190
191#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
192pub enum SlackConversationType {
193 #[serde(rename = "im")]
194 Im,
195 #[serde(rename = "mpim")]
196 Mpim,
197 #[serde(rename = "private_channel")]
198 Private,
199 #[serde(rename = "public_channel")]
200 Public,
201}
202
203#[allow(clippy::to_string_trait_impl)]
204impl ToString for SlackConversationType {
205 fn to_string(&self) -> String {
206 match self {
207 SlackConversationType::Im => "im".into(),
208 SlackConversationType::Mpim => "mpim".into(),
209 SlackConversationType::Private => "private_channel".into(),
210 SlackConversationType::Public => "public_channel".into(),
211 }
212 }
213}
214
215#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
216pub struct SlackResponseUrl(pub Url);
217
218#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
219pub struct SlackWebSocketsUrl(pub Url);
220
221impl SlackWebSocketsUrl {
222 pub fn to_debug_url(&self) -> Self {
223 Self(Url::parse(format!("{}&debug_reconnects=true", self.value()).as_str()).unwrap())
224 }
225}
226
227#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
228pub struct SlackTeamUrl(pub Url);
229
230#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
231pub struct SlackUnfurlId(pub String);
232
233#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
234pub struct SlackMimeType(pub String);
235
236#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
237pub struct SlackEmoji(pub String);
238
239impl SlackEmoji {
240 pub const SMILE: &'static str = ":smile:";
241 pub const SPEECH_BALLOON: &'static str = ":speech_balloon:";
242 pub const HEAVY_CHECK_MARK: &'static str = ":heavy_check_mark:";
243}
244
245#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
246pub enum SlackShortcutType {
247 #[serde(rename = "message")]
248 Message,
249 #[serde(rename = "global")]
250 Global,
251}
252
253#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, ValueStruct)]
254pub struct SlackEventType(pub String);
255
256#[derive(Debug, Eq, Hash, PartialEq, Clone, Serialize, Deserialize, ValueStruct)]
257pub struct SlackEnterpriseId(pub String);
258
259#[cfg(test)]
260mod test {
261 use super::*;
262
263 #[test]
264 fn test_slack_date_time() {
265 let dt = SlackDateTime(
266 DateTime::parse_from_rfc3339("2020-01-01T00:42:42Z")
267 .unwrap()
268 .into(),
269 );
270 let json = serde_json::to_value(&dt).unwrap();
271 assert_eq!(json.as_u64().unwrap(), 1577839362);
272 }
273}