ids.rs

  1use crate::Result;
  2use rpc::proto;
  3use sea_orm::{entity::prelude::*, DbErr};
  4use serde::{Deserialize, Serialize};
  5
  6macro_rules! id_type {
  7    ($name:ident) => {
  8        #[derive(
  9            Clone,
 10            Copy,
 11            Debug,
 12            Default,
 13            PartialEq,
 14            Eq,
 15            PartialOrd,
 16            Ord,
 17            Hash,
 18            Serialize,
 19            Deserialize,
 20            DeriveValueType,
 21        )]
 22        #[serde(transparent)]
 23        pub struct $name(pub i32);
 24
 25        impl $name {
 26            #[allow(unused)]
 27            pub const MAX: Self = Self(i32::MAX);
 28
 29            #[allow(unused)]
 30            pub fn from_proto(value: u64) -> Self {
 31                Self(value as i32)
 32            }
 33
 34            #[allow(unused)]
 35            pub fn to_proto(self) -> u64 {
 36                self.0 as u64
 37            }
 38        }
 39
 40        impl std::fmt::Display for $name {
 41            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 42                self.0.fmt(f)
 43            }
 44        }
 45
 46        impl sea_orm::TryFromU64 for $name {
 47            fn try_from_u64(n: u64) -> Result<Self, DbErr> {
 48                Ok(Self(n.try_into().map_err(|_| {
 49                    DbErr::ConvertFromU64(concat!(
 50                        "error converting ",
 51                        stringify!($name),
 52                        " to u64"
 53                    ))
 54                })?))
 55            }
 56        }
 57
 58        impl sea_orm::sea_query::Nullable for $name {
 59            fn null() -> Value {
 60                Value::Int(None)
 61            }
 62        }
 63    };
 64}
 65
 66id_type!(BufferId);
 67id_type!(AccessTokenId);
 68id_type!(ChannelChatParticipantId);
 69id_type!(ChannelId);
 70id_type!(ChannelMemberId);
 71id_type!(MessageId);
 72id_type!(ContactId);
 73id_type!(FollowerId);
 74id_type!(RoomId);
 75id_type!(RoomParticipantId);
 76id_type!(ProjectId);
 77id_type!(ProjectCollaboratorId);
 78id_type!(ReplicaId);
 79id_type!(ServerId);
 80id_type!(SignupId);
 81id_type!(UserId);
 82id_type!(ChannelBufferCollaboratorId);
 83id_type!(FlagId);
 84id_type!(NotificationId);
 85id_type!(NotificationKindId);
 86
 87#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
 88#[sea_orm(rs_type = "String", db_type = "String(None)")]
 89pub enum ChannelRole {
 90    #[sea_orm(string_value = "admin")]
 91    Admin,
 92    #[sea_orm(string_value = "member")]
 93    #[default]
 94    Member,
 95    #[sea_orm(string_value = "guest")]
 96    Guest,
 97    #[sea_orm(string_value = "banned")]
 98    Banned,
 99}
100
101impl ChannelRole {
102    pub fn should_override(&self, other: Self) -> bool {
103        use ChannelRole::*;
104        match self {
105            Admin => matches!(other, Member | Banned | Guest),
106            Member => matches!(other, Banned | Guest),
107            Banned => matches!(other, Guest),
108            Guest => false,
109        }
110    }
111
112    pub fn max(&self, other: Self) -> Self {
113        if self.should_override(other) {
114            *self
115        } else {
116            other
117        }
118    }
119
120    pub fn can_see_all_descendants(&self) -> bool {
121        use ChannelRole::*;
122        match self {
123            Admin | Member => true,
124            Guest | Banned => false,
125        }
126    }
127
128    pub fn can_only_see_public_descendants(&self) -> bool {
129        use ChannelRole::*;
130        match self {
131            Guest => true,
132            Admin | Member | Banned => false,
133        }
134    }
135
136    pub fn can_share_projects(&self) -> bool {
137        use ChannelRole::*;
138        match self {
139            Admin | Member => true,
140            Guest | Banned => false,
141        }
142    }
143
144    pub fn can_edit_projects(&self) -> bool {
145        use ChannelRole::*;
146        match self {
147            Admin | Member => true,
148            Guest | Banned => false,
149        }
150    }
151
152    pub fn can_read_projects(&self) -> bool {
153        use ChannelRole::*;
154        match self {
155            Admin | Member | Guest => true,
156            Banned => false,
157        }
158    }
159}
160
161impl From<proto::ChannelRole> for ChannelRole {
162    fn from(value: proto::ChannelRole) -> Self {
163        match value {
164            proto::ChannelRole::Admin => ChannelRole::Admin,
165            proto::ChannelRole::Member => ChannelRole::Member,
166            proto::ChannelRole::Guest => ChannelRole::Guest,
167            proto::ChannelRole::Banned => ChannelRole::Banned,
168        }
169    }
170}
171
172impl Into<proto::ChannelRole> for ChannelRole {
173    fn into(self) -> proto::ChannelRole {
174        match self {
175            ChannelRole::Admin => proto::ChannelRole::Admin,
176            ChannelRole::Member => proto::ChannelRole::Member,
177            ChannelRole::Guest => proto::ChannelRole::Guest,
178            ChannelRole::Banned => proto::ChannelRole::Banned,
179        }
180    }
181}
182
183impl Into<i32> for ChannelRole {
184    fn into(self) -> i32 {
185        let proto: proto::ChannelRole = self.into();
186        proto.into()
187    }
188}
189
190#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
191#[sea_orm(rs_type = "String", db_type = "String(None)")]
192pub enum ChannelVisibility {
193    #[sea_orm(string_value = "public")]
194    Public,
195    #[sea_orm(string_value = "members")]
196    #[default]
197    Members,
198}
199
200impl From<proto::ChannelVisibility> for ChannelVisibility {
201    fn from(value: proto::ChannelVisibility) -> Self {
202        match value {
203            proto::ChannelVisibility::Public => ChannelVisibility::Public,
204            proto::ChannelVisibility::Members => ChannelVisibility::Members,
205        }
206    }
207}
208
209impl Into<proto::ChannelVisibility> for ChannelVisibility {
210    fn into(self) -> proto::ChannelVisibility {
211        match self {
212            ChannelVisibility::Public => proto::ChannelVisibility::Public,
213            ChannelVisibility::Members => proto::ChannelVisibility::Members,
214        }
215    }
216}
217
218impl Into<i32> for ChannelVisibility {
219    fn into(self) -> i32 {
220        let proto: proto::ChannelVisibility = self.into();
221        proto.into()
222    }
223}