slack_morphism/models/common/
mod.rs

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}