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::*;
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}