summary refs log tree commit diff
path: root/src/mattermost/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mattermost/model.rs')
-rw-r--r--src/mattermost/model.rs152
1 files changed, 96 insertions, 56 deletions
diff --git a/src/mattermost/model.rs b/src/mattermost/model.rs
index d928359..b8090c8 100644
--- a/src/mattermost/model.rs
+++ b/src/mattermost/model.rs
@@ -1,94 +1,106 @@
+use serde_with::serde_as;
+use std::collections::HashMap;
+
 use serde::Deserialize;
 type PostId = String;
+type TeamId = String;
 type UserId = String;
+type ChannelId = String;
 
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 #[serde(untagged)]
 pub enum WebsocketMessage {
     Update(WebsocketUpdate),
     Reply(WebsocketReply),
 }
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct WebsocketReply {
     pub status: String,
     pub seq_reply: u32,
 }
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[serde_as]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct Broadcast {
-    pub channel_id: String,
-    pub connection_id: String,
-    pub omit_connection_id: String,
-    // omit_users:
-    pub team_id: String,
-    pub user_id: String,
+    #[serde_as(as = "serde_with::NoneAsEmptyString")]
+    pub channel_id: Option<ChannelId>,
+    #[serde_as(as = "serde_with::NoneAsEmptyString")]
+    pub connection_id: Option<String>,
+    #[serde_as(as = "serde_with::NoneAsEmptyString")]
+    pub omit_connection_id: Option<String>,
+    #[serde(default)]
+    pub omit_users: Option<HashMap<UserId, bool>>,
+    #[serde_as(as = "serde_with::NoneAsEmptyString")]
+    pub team_id: Option<TeamId>,
+    #[serde_as(as = "serde_with::NoneAsEmptyString")]
+    pub user_id: Option<UserId>,
+    #[serde(default)]
+    pub contains_sanitized_data: bool,
 }
-#[derive(Deserialize, Debug, PartialEq, Eq)]
-pub struct WebsocketUpdateStuff {
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
+pub struct WebsocketUpdateFields {
     pub broadcast: Broadcast,
     pub seq: u32,
 }
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct WebsocketUpdate {
     #[serde(flatten)]
-    pub stuff: WebsocketUpdateStuff,
+    pub stuff: WebsocketUpdateFields,
     #[serde(flatten)]
     pub update: Update,
 }
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 #[serde(tag = "event", content = "data")]
 pub enum Update {
-    #[serde(rename = "posted")]
-    Posted(Posted),
     #[serde(rename = "hello")]
     Hello(Hello),
+    #[serde(rename = "new_user")]
+    NewUser { user_id: UserId },
+    #[serde(rename = "user_updated")]
+    UserUpdated(UserUpdated),
+    #[serde(rename = "posted")]
+    Posted(Posted),
     #[serde(rename = "status_change")]
     StatusChange {},
     #[serde(rename = "typing")]
     Typing {},
     #[serde(rename = "channel_viewed")]
     ChannelViewed {},
-    #[serde(other)]
-    Other,
+    #[serde(rename = "multiple_channels_viewed")]
+    MultipleChannelViewed {},
+    // #[serde(other)]
+    // Other,
 }
 
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[serde_as]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct Posted {
     pub channel_display_name: String,
     pub channel_name: String,
     pub channel_type: String,
-    #[serde(deserialize_with = "deserialize_json_field", default)]
+    #[serde_as(as = "serde_with::json::JsonString")]
+    #[serde(default)]
     pub mentions: Vec<String>,
-    #[serde(deserialize_with = "deserialize_json_field")]
+    #[serde_as(as = "serde_with::json::JsonString")]
     pub post: Post,
 }
-fn deserialize_json_field<'de, D, T>(deserializer: D) -> Result<T, D::Error>
-where
-    D: serde::Deserializer<'de>,
-    T: serde::de::DeserializeOwned,
-{
-    let buf: String = String::deserialize(deserializer)?;
-    serde_json::from_str(&buf).map_err(|x| {
-        serde::de::Error::custom(format!("Error while deserializing json encoded field {x}"))
-    })
-}
 
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct Post {
-    pub id: String,
+    pub id: PostId,
     pub create_at: u64,
     pub update_at: u64,
     pub edit_at: u64,
     pub delete_at: u64,
     pub is_pinned: bool,
-    pub user_id: String,
-    pub channel_id: String,
+    pub user_id: UserId,
+    pub channel_id: ChannelId,
     // pub hashtags: String,
     // pub last_reply_at: u64,
     pub message: String,
     // pub metadata:,
-    // pub original_id: String,
+    // pub original_id: PostId,
     // pub participants:,
-    // pub pending_post_id: String,
+    // pub pending_post_id: PostId,
     // pub preops
     // pub reply_count: u64,
     pub root_id: String,
@@ -96,7 +108,36 @@ pub struct Post {
     pub ttype: String,
 }
 
-#[derive(Deserialize, Debug, PartialEq, Eq)]
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
+pub struct UserUpdated {
+    pub id: UserId,
+    pub create_at: u64,
+    pub update_at: u64,
+    pub delete_at: u64,
+    pub username: String,
+    pub authdata: String,
+    pub auth_service: String,
+    pub email: String,
+    pub nickname: String,
+    pub first_name: String,
+    pub last_name: String,
+    pub position: String,
+    pub roles: String,
+    pub locale: String,
+    pub timezone: Timezone,
+    pub disable_welcome_email: bool,
+}
+
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
+pub struct Timezone {
+    #[serde(rename = "automaticTimezone")]
+    pub automatic_timezone: String,
+    #[serde(rename = "manualTimezone")]
+    pub manual_timezone: String,
+    #[serde(rename = "useAutomaticTimezone")]
+    pub use_automatic_timezone: String,
+}
+#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
 pub struct Hello {
     pub connection_id: String,
     pub server_version: String,
@@ -106,7 +147,7 @@ mod tests {
     use serde_json::Value;
 
     use crate::mattermost::model::{
-        Broadcast, Post, Update, WebsocketUpdate, WebsocketUpdateStuff,
+        Broadcast, Post, Update, WebsocketMessage, WebsocketUpdate, WebsocketUpdateFields,
     };
     #[test]
     fn parse_post() {
@@ -204,6 +245,15 @@ mod tests {
     }
     #[test]
     fn parse_websocketupdate() {
+        let broadcast = Broadcast {
+            channel_id: Some("a".to_owned()),
+            connection_id: Some("b".to_owned()),
+            omit_connection_id: Some("c".to_owned()),
+            team_id: Some("d".to_owned()),
+            user_id: Some("e".to_owned()),
+            omit_users: None,
+            contains_sanitized_data: false,
+        };
         let post = Post {
             id: "a".to_owned(),
             create_at: 1,
@@ -237,14 +287,8 @@ mod tests {
         assert_eq!(
             update.unwrap(),
             WebsocketUpdate {
-                stuff: WebsocketUpdateStuff {
-                    broadcast: Broadcast {
-                        channel_id: "a".to_owned(),
-                        connection_id: "b".to_owned(),
-                        omit_connection_id: "c".to_owned(),
-                        team_id: "d".to_owned(),
-                        user_id: "e".to_owned()
-                    },
+                stuff: WebsocketUpdateFields {
+                    broadcast: broadcast.clone(),
                     seq: 2137,
                 },
                 update: Update::Hello(super::Hello {
@@ -276,14 +320,8 @@ mod tests {
         assert_eq!(
             update.unwrap(),
             WebsocketUpdate {
-                stuff: WebsocketUpdateStuff {
-                    broadcast: Broadcast {
-                        channel_id: "a".to_owned(),
-                        connection_id: "b".to_owned(),
-                        omit_connection_id: "c".to_owned(),
-                        team_id: "d".to_owned(),
-                        user_id: "e".to_owned()
-                    },
+                stuff: WebsocketUpdateFields {
+                    broadcast: broadcast.clone(),
                     seq: 2137,
                 },
                 update: Update::Posted(super::Posted {
@@ -300,6 +338,8 @@ mod tests {
     fn parse_realexamples() {
         let data = r#"{"event":"posted","data":{"channel_display_name":"a","channel_name":"a","channel_type":"O","post":"{\"id\":\"b\",\"create_at\":1,\"update_at\":2,\"edit_at\":0,\"delete_at\":0,\"is_pinned\":false,\"user_id\":\"b\",\"channel_id\":\"c\",\"root_id\":\"\",\"original_id\":\"\",\"message\":\"blah\",\"type\":\"\",\"props\":{\"disable_group_highlight\":true},\"hashtags\":\"\",\"pending_post_id\":\"d\",\"reply_count\":0,\"last_reply_at\":0,\"participants\":null,\"metadata\":{}}","sender_name":"@blah","set_online":true,"team_id":"e"},"broadcast":{"omit_users":null,"user_id":"","channel_id":"f","team_id":"","connection_id":"","omit_connection_id":""},"seq":3}"#;
 
-        serde_json::from_str::<WebsocketUpdate>(data).unwrap();
+        serde_json::from_str::<WebsocketMessage>(data).unwrap();
+        let data = r#"{"event": "multiple_channels_viewed", "data": {"channel_times":{"aaaa":1706319279901}}, "broadcast": {"omit_users":null,"user_id":"bbbb","channel_id":"","team_id":"","connection_id":"","omit_connection_id":""}, "seq": 6}"#;
+        serde_json::from_str::<WebsocketMessage>(data).unwrap();
     }
 }