1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use crate::{
    attachment::Attachment,
    permission::{OverrideField, Permission},
};

/// Representation of a channel on Revolt
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "channel_type")]
pub enum Channel {
    /// Personal "Saved Notes" channel which allows users to save messages
    SavedMessages {
        /// Unique Id
        #[serde(rename = "_id")]
        id: String,
        /// Id of the user this channel belongs to
        user: String,
    },

    /// Direct message channel between two users
    DirectMessage {
        /// Unique Id
        #[serde(rename = "_id")]
        id: String,

        /// Whether this direct message channel is currently open on both sides
        active: bool,
        /// 2-tuple of user ids participating in direct message
        recipients: Vec<String>,
        /// Id of the last message sent in this channel
        last_message_id: Option<String>,
    },

    /// Group channel between 1 or more participants
    Group {
        /// Unique Id
        #[serde(rename = "_id")]
        id: String,

        /// Display name of the channel
        name: String,
        /// User id of the owner of the group
        owner: String,
        /// Channel description
        description: Option<String>,
        /// Array of user ids participating in channel
        recipients: Vec<String>,

        /// Custom icon attachment
        icon: Option<Attachment>,
        /// Id of the last message sent in this channel
        last_message_id: Option<String>,

        /// Permissions assigned to members of this group
        /// (does not apply to the owner of the group)
        permissions: Option<Permission>,

        /// Whether this group is marked as not safe for work
        #[serde(default)]
        nsfw: bool,
    },

    /// Text channel belonging to a server
    TextChannel {
        /// Unique Id
        #[serde(rename = "_id")]
        id: String,
        /// Id of the server this channel belongs to
        server: String,

        /// Display name of the channel
        name: String,
        /// Channel description
        description: Option<String>,

        /// Custom icon attachment
        icon: Option<Attachment>,
        /// Id of the last message sent in this channel
        last_message_id: Option<String>,

        /// Default permissions assigned to users in this channel
        default_permissions: Option<OverrideField>,
        /// Permissions assigned based on role to this channel
        #[serde(default = "HashMap::<String, OverrideField>::new")]
        role_permissions: HashMap<String, OverrideField>,

        /// Whether this channel is marked as not safe for work
        #[serde(default)]
        nsfw: bool,
    },

    /// Voice channel belonging to a server
    VoiceChannel {
        /// Unique Id
        #[serde(rename = "_id")]
        id: String,
        /// Id of the server this channel belongs to
        server: String,

        /// Display name of the channel
        name: String,
        /// Channel description
        description: Option<String>,
        /// Custom icon attachment
        icon: Option<Attachment>,

        /// Default permissions assigned to users in this channel
        default_permissions: Option<OverrideField>,
        /// Permissions assigned based on role to this channel
        #[serde(default = "HashMap::<String, OverrideField>::new")]
        role_permissions: HashMap<String, OverrideField>,

        /// Whether this channel is marked as not safe for work
        #[serde(default)]
        nsfw: bool,
    },
}

/// Partial values of [Channel]
#[derive(Deserialize, Debug, Default, Clone)]
pub struct PartialChannel {
    /// Display name of the channel
    pub name: Option<String>,
    /// User id of the owner of the group
    pub owner: Option<String>,
    /// Channel description
    pub description: Option<String>,
    /// Custom icon attachment
    pub icon: Option<Attachment>,
    /// Whether this channel is marked as not safe for work
    pub nsfw: Option<bool>,
    /// Whether this direct message channel is currently open on both sides
    pub active: Option<bool>,
    /// Permissions assigned to members of this channel
    pub permissions: Option<Permission>,
    /// Permissions assigned based on role to this channel
    pub role_permissions: Option<HashMap<String, OverrideField>>,
    /// Default permissions assigned to users in this channel
    pub default_permissions: Option<OverrideField>,
    /// Id of the last message sent in this channel
    pub last_message_id: Option<String>,
}

/// Channel type
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum ChannelType {
    Text,
    Voice,
}

impl Default for ChannelType {
    fn default() -> Self {
        ChannelType::Text
    }
}

/// Optional fields on channel object
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum FieldsChannel {
    Description,
    Icon,
    DefaultPermissions,
}

/// Representation of an invite to a channel on Revolt
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum PartialInvite {
    /// Invite to a specific server channel
    Server {
        /// Invite code
        #[serde(rename = "_id")]
        code: String,
        /// Id of the server this invite points to
        server: String,
        /// Id of user who created this invite
        creator: String,
        /// Id of the server channel this invite points to
        channel: String,
    },
    /// Invite to a group channel
    Group {
        /// Invite code
        #[serde(rename = "_id")]
        code: String,
        /// Id of user who created this invite
        creator: String,
        /// Id of the group channel this invite points to
        channel: String,
    },
}

/// Composite primary key consisting of channel and user ID
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct ChannelCompositeKey {
    /// Channel ID
    pub channel: String,
    /// User ID
    pub user: String,
}

/// Representation of the state of a channel from the perspective of a user
#[derive(Deserialize, Debug, Clone)]
pub struct ChannelUnread {
    /// Composite key pointing to a user's view of a channel
    #[serde(rename = "_id")]
    pub id: ChannelCompositeKey,

    /// ID of the last message read in this channel by a user
    pub last_id: Option<String>,
    /// Array of message ids that mention the user
    pub mentions: Option<Vec<String>>,
}