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