1use crate::Result;
2use rpc::proto;
3use sea_orm::{DbErr, entity::prelude::*};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7#[macro_export]
8macro_rules! id_type {
9 ($name:ident) => {
10 #[derive(
11 Clone,
12 Copy,
13 Debug,
14 Default,
15 PartialEq,
16 Eq,
17 PartialOrd,
18 Ord,
19 Hash,
20 Serialize,
21 Deserialize,
22 DeriveValueType,
23 )]
24 #[allow(missing_docs)]
25 #[serde(transparent)]
26 pub struct $name(pub i32);
27
28 impl $name {
29 #[allow(unused)]
30 #[allow(missing_docs)]
31 pub const MAX: Self = Self(i32::MAX);
32
33 #[allow(unused)]
34 #[allow(missing_docs)]
35 pub fn from_proto(value: u64) -> Self {
36 debug_assert!(value != 0);
37 Self(value as i32)
38 }
39
40 #[allow(unused)]
41 #[allow(missing_docs)]
42 pub fn to_proto(self) -> u64 {
43 self.0 as u64
44 }
45 }
46
47 impl std::fmt::Display for $name {
48 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49 self.0.fmt(f)
50 }
51 }
52
53 impl sea_orm::TryFromU64 for $name {
54 fn try_from_u64(n: u64) -> Result<Self, DbErr> {
55 Ok(Self(n.try_into().map_err(|_| {
56 DbErr::ConvertFromU64(concat!(
57 "error converting ",
58 stringify!($name),
59 " to u64"
60 ))
61 })?))
62 }
63 }
64
65 impl sea_orm::sea_query::Nullable for $name {
66 fn null() -> Value {
67 Value::Int(None)
68 }
69 }
70 };
71}
72
73id_type!(AccessTokenId);
74id_type!(BufferId);
75id_type!(ChannelBufferCollaboratorId);
76id_type!(ChannelChatParticipantId);
77id_type!(ChannelId);
78id_type!(ChannelMemberId);
79id_type!(ContactId);
80id_type!(ExtensionId);
81id_type!(FlagId);
82id_type!(FollowerId);
83id_type!(HostedProjectId);
84id_type!(MessageId);
85id_type!(NotificationId);
86id_type!(NotificationKindId);
87id_type!(ProjectCollaboratorId);
88id_type!(ProjectId);
89id_type!(ReplicaId);
90id_type!(RoomId);
91id_type!(RoomParticipantId);
92id_type!(ServerId);
93id_type!(SignupId);
94id_type!(UserId);
95
96#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, DeriveValueType)]
97pub struct SharedThreadId(pub Uuid);
98
99impl SharedThreadId {
100 pub fn from_proto(id: String) -> Option<Self> {
101 Uuid::parse_str(&id).ok().map(SharedThreadId)
102 }
103
104 pub fn to_proto(self) -> String {
105 self.0.to_string()
106 }
107}
108
109impl sea_orm::TryFromU64 for SharedThreadId {
110 fn try_from_u64(_n: u64) -> std::result::Result<Self, DbErr> {
111 Err(DbErr::ConvertFromU64(
112 "SharedThreadId uses UUID and cannot be converted from u64",
113 ))
114 }
115}
116
117impl sea_orm::sea_query::Nullable for SharedThreadId {
118 fn null() -> Value {
119 Value::Uuid(None)
120 }
121}
122
123impl std::fmt::Display for SharedThreadId {
124 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
125 self.0.fmt(f)
126 }
127}
128
129/// ChannelRole gives you permissions for both channels and calls.
130#[derive(
131 Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash, Serialize,
132)]
133#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
134pub enum ChannelRole {
135 /// Admin can read/write and change permissions.
136 #[sea_orm(string_value = "admin")]
137 Admin,
138 /// Member can read/write, but not change permissions.
139 #[sea_orm(string_value = "member")]
140 #[default]
141 Member,
142 /// Talker can read, but not write.
143 /// They can use microphones and the channel chat
144 #[sea_orm(string_value = "talker")]
145 Talker,
146 /// Guest can read, but not write.
147 /// They can not use microphones but can use the chat.
148 #[sea_orm(string_value = "guest")]
149 Guest,
150 /// Banned may not read.
151 #[sea_orm(string_value = "banned")]
152 Banned,
153}
154
155impl ChannelRole {
156 /// Returns true if this role is more powerful than the other role.
157 pub fn should_override(&self, other: Self) -> bool {
158 use ChannelRole::*;
159 match self {
160 Admin => matches!(other, Member | Banned | Talker | Guest),
161 Member => matches!(other, Banned | Talker | Guest),
162 Talker => matches!(other, Guest),
163 Banned => matches!(other, Guest),
164 Guest => false,
165 }
166 }
167
168 /// Returns the maximal role between the two
169 pub fn max(&self, other: Self) -> Self {
170 if self.should_override(other) {
171 *self
172 } else {
173 other
174 }
175 }
176
177 pub fn can_see_channel(&self, visibility: ChannelVisibility) -> bool {
178 use ChannelRole::*;
179 match self {
180 Admin | Member => true,
181 Guest | Talker => visibility == ChannelVisibility::Public,
182 Banned => false,
183 }
184 }
185
186 /// True if the role allows access to all descendant channels
187 pub fn can_see_all_descendants(&self) -> bool {
188 use ChannelRole::*;
189 match self {
190 Admin | Member => true,
191 Guest | Talker | Banned => false,
192 }
193 }
194
195 /// True if the role only allows access to public descendant channels
196 pub fn can_only_see_public_descendants(&self) -> bool {
197 use ChannelRole::*;
198 match self {
199 Guest | Talker => true,
200 Admin | Member | Banned => false,
201 }
202 }
203
204 /// True if the role can share screen/microphone/projects into rooms.
205 pub fn can_use_microphone(&self) -> bool {
206 use ChannelRole::*;
207 match self {
208 Admin | Member | Talker => true,
209 Guest | Banned => false,
210 }
211 }
212
213 /// True if the role can edit shared projects.
214 pub fn can_edit_projects(&self) -> bool {
215 use ChannelRole::*;
216 match self {
217 Admin | Member => true,
218 Talker | Guest | Banned => false,
219 }
220 }
221
222 /// True if the role can read shared projects.
223 pub fn can_read_projects(&self) -> bool {
224 use ChannelRole::*;
225 match self {
226 Admin | Member | Guest | Talker => true,
227 Banned => false,
228 }
229 }
230
231 pub fn requires_cla(&self) -> bool {
232 use ChannelRole::*;
233 match self {
234 Admin | Member => true,
235 Banned | Guest | Talker => false,
236 }
237 }
238}
239
240impl From<proto::ChannelRole> for ChannelRole {
241 fn from(value: proto::ChannelRole) -> Self {
242 match value {
243 proto::ChannelRole::Admin => ChannelRole::Admin,
244 proto::ChannelRole::Member => ChannelRole::Member,
245 proto::ChannelRole::Talker => ChannelRole::Talker,
246 proto::ChannelRole::Guest => ChannelRole::Guest,
247 proto::ChannelRole::Banned => ChannelRole::Banned,
248 }
249 }
250}
251
252impl From<ChannelRole> for proto::ChannelRole {
253 fn from(val: ChannelRole) -> Self {
254 match val {
255 ChannelRole::Admin => proto::ChannelRole::Admin,
256 ChannelRole::Member => proto::ChannelRole::Member,
257 ChannelRole::Talker => proto::ChannelRole::Talker,
258 ChannelRole::Guest => proto::ChannelRole::Guest,
259 ChannelRole::Banned => proto::ChannelRole::Banned,
260 }
261 }
262}
263
264impl From<ChannelRole> for i32 {
265 fn from(val: ChannelRole) -> Self {
266 let proto: proto::ChannelRole = val.into();
267 proto.into()
268 }
269}
270
271/// ChannelVisibility controls whether channels are public or private.
272#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
273#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)")]
274pub enum ChannelVisibility {
275 /// Public channels are visible to anyone with the link. People join with the Guest role by default.
276 #[sea_orm(string_value = "public")]
277 Public,
278 /// Members channels are only visible to members of this channel or its parents.
279 #[sea_orm(string_value = "members")]
280 #[default]
281 Members,
282}
283
284impl From<proto::ChannelVisibility> for ChannelVisibility {
285 fn from(value: proto::ChannelVisibility) -> Self {
286 match value {
287 proto::ChannelVisibility::Public => ChannelVisibility::Public,
288 proto::ChannelVisibility::Members => ChannelVisibility::Members,
289 }
290 }
291}
292
293impl From<ChannelVisibility> for proto::ChannelVisibility {
294 fn from(val: ChannelVisibility) -> Self {
295 match val {
296 ChannelVisibility::Public => proto::ChannelVisibility::Public,
297 ChannelVisibility::Members => proto::ChannelVisibility::Members,
298 }
299 }
300}
301
302impl From<ChannelVisibility> for i32 {
303 fn from(val: ChannelVisibility) -> Self {
304 let proto: proto::ChannelVisibility = val.into();
305 proto.into()
306 }
307}
308
309/// Indicate whether a [Buffer] has permissions to edit.
310#[derive(PartialEq, Clone, Copy, Debug)]
311pub enum Capability {
312 /// The buffer is a mutable replica.
313 ReadWrite,
314 /// The buffer is a read-only replica.
315 ReadOnly,
316}