twilight_model/channel/thread/
member.rs

1use crate::{
2    gateway::presence::{Presence, PresenceIntermediary},
3    guild::Member,
4    id::{
5        marker::{ChannelMarker, GuildMarker, UserMarker},
6        Id,
7    },
8    util::Timestamp,
9};
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
13pub struct ThreadMember {
14    // Values currently unknown and undocumented.
15    pub flags: u64,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub id: Option<Id<ChannelMarker>>,
18    pub join_timestamp: Timestamp,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub member: Option<Member>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub presence: Option<Presence>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub user_id: Option<Id<UserMarker>>,
25}
26
27/// Version of [`ThreadMember`], but without a guild ID in the
28/// [`Self::member`] field.
29#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq)]
30pub(crate) struct ThreadMemberIntermediary {
31    // Values currently unknown and undocumented.
32    pub flags: u64,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub id: Option<Id<ChannelMarker>>,
35    pub join_timestamp: Timestamp,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub member: Option<Member>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub presence: Option<PresenceIntermediary>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub user_id: Option<Id<UserMarker>>,
42}
43
44impl ThreadMemberIntermediary {
45    /// Inject a guild ID into a thread member intermediary
46    pub fn into_thread_member(self, guild_id: Id<GuildMarker>) -> ThreadMember {
47        let presence = self.presence.map(|p| p.into_presence(guild_id));
48        ThreadMember {
49            flags: self.flags,
50            id: self.id,
51            join_timestamp: self.join_timestamp,
52            member: self.member,
53            presence,
54            user_id: self.user_id,
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::ThreadMember;
62    use crate::{
63        id::Id,
64        util::datetime::{Timestamp, TimestampParseError},
65    };
66    use serde_test::Token;
67    use std::str::FromStr;
68
69    #[test]
70    fn thread_member() -> Result<(), TimestampParseError> {
71        const DATETIME: &str = "2021-09-19T14:17:32.000000+00:00";
72
73        let join_timestamp = Timestamp::from_str(DATETIME)?;
74
75        let value = ThreadMember {
76            flags: 3,
77            id: Some(Id::new(1)),
78            member: None,
79            presence: None,
80            join_timestamp,
81            user_id: Some(Id::new(2)),
82        };
83
84        serde_test::assert_tokens(
85            &value,
86            &[
87                Token::Struct {
88                    name: "ThreadMember",
89                    len: 4,
90                },
91                Token::Str("flags"),
92                Token::U64(3),
93                Token::Str("id"),
94                Token::Some,
95                Token::NewtypeStruct { name: "Id" },
96                Token::Str("1"),
97                Token::Str("join_timestamp"),
98                Token::Str(DATETIME),
99                Token::Str("user_id"),
100                Token::Some,
101                Token::NewtypeStruct { name: "Id" },
102                Token::Str("2"),
103                Token::StructEnd,
104            ],
105        );
106
107        Ok(())
108    }
109}