diff options
Diffstat (limited to 'src/mattermost/model.rs')
-rw-r--r-- | src/mattermost/model.rs | 152 |
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(); } } |