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_publish_to_rooms(&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}