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