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