ids.rs

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