libsignal_service/groups_v2/
model.rs1use std::{convert::TryFrom, convert::TryInto};
2
3use derivative::Derivative;
4use libsignal_protocol::ServiceId;
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7use zkgroup::profiles::ProfileKey;
8
9use super::GroupDecodingError;
10
11#[derive(Copy, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
12pub enum Role {
13 Unknown,
14 Default,
15 Administrator,
16}
17
18#[derive(Derivative, Clone, Deserialize, Serialize)]
19#[derivative(Debug)]
20pub struct Member {
21 pub uuid: Uuid,
22 pub role: Role,
23 #[derivative(Debug = "ignore")]
24 pub profile_key: ProfileKey,
25 pub joined_at_revision: u32,
26}
27
28impl PartialEq for Member {
29 fn eq(&self, other: &Self) -> bool {
30 self.uuid == other.uuid
31 }
32}
33
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub struct PendingMember {
36 pub address: ServiceId,
37 pub role: Role,
38 pub added_by_uuid: Uuid,
39 pub timestamp: u64,
40}
41
42#[derive(Derivative, Clone)]
43#[derivative(Debug)]
44pub struct RequestingMember {
45 pub uuid: Uuid,
46 #[derivative(Debug = "ignore")]
47 pub profile_key: ProfileKey,
48 pub timestamp: u64,
49}
50
51impl PartialEq for RequestingMember {
52 fn eq(&self, other: &Self) -> bool {
53 self.uuid == other.uuid
54 }
55}
56
57#[derive(Copy, Debug, Clone, PartialEq, Serialize, Deserialize)]
58pub enum AccessRequired {
59 Unknown,
60 Any,
61 Member,
62 Administrator,
63 Unsatisfiable,
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
67pub struct AccessControl {
68 pub attributes: AccessRequired,
69 pub members: AccessRequired,
70 pub add_from_invite_link: AccessRequired,
71}
72
73#[derive(Debug, Clone, PartialEq)]
74pub struct Group {
75 pub title: String,
76 pub avatar: String,
77 pub disappearing_messages_timer: Option<Timer>,
78 pub access_control: Option<AccessControl>,
79 pub revision: u32,
80 pub members: Vec<Member>,
81 pub pending_members: Vec<PendingMember>,
82 pub requesting_members: Vec<RequestingMember>,
83 pub invite_link_password: Vec<u8>,
84 pub description: Option<String>,
85}
86
87#[derive(Debug, Clone)]
88pub struct GroupChanges {
89 pub editor: Uuid,
90 pub revision: u32,
91 pub changes: Vec<GroupChange>,
92}
93
94#[derive(Derivative, Clone)]
95#[derivative(Debug)]
96pub enum GroupChange {
97 NewMember(Member),
98 DeleteMember(Uuid),
99 ModifyMemberRole {
100 uuid: Uuid,
101 role: Role,
102 },
103 ModifyMemberProfileKey {
104 uuid: Uuid,
105 #[derivative(Debug = "ignore")]
106 profile_key: ProfileKey,
107 },
108 NewPendingMember(PendingMember),
110 DeletePendingMember(Uuid),
111 PromotePendingMember {
112 uuid: Uuid,
113 #[derivative(Debug = "ignore")]
114 profile_key: ProfileKey,
115 },
116 NewRequestingMember(RequestingMember),
118 DeleteRequestingMember(Uuid),
119 PromoteRequestingMember {
120 uuid: Uuid,
121 role: Role,
122 },
123 Title(String),
125 Avatar(String),
126 Timer(Option<Timer>),
127 Description(Option<String>),
128 AttributeAccess(AccessRequired),
129 MemberAccess(AccessRequired),
130 InviteLinkAccess(AccessRequired),
131 InviteLinkPassword(String),
132 AnnouncementOnly(bool),
133}
134
135#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
136pub struct Timer {
137 pub duration: u32,
138}
139
140impl TryFrom<i32> for Role {
143 type Error = GroupDecodingError;
144
145 fn try_from(value: i32) -> Result<Self, Self::Error> {
146 use crate::proto::member::Role::*;
147 match crate::proto::member::Role::try_from(value) {
148 Ok(Unknown) => Ok(Role::Unknown),
149 Ok(Default) => Ok(Role::Default),
150 Ok(Administrator) => Ok(Role::Administrator),
151 Err(_e) => Err(GroupDecodingError::WrongEnumValue),
152 }
153 }
154}
155
156impl From<Role> for i32 {
157 fn from(val: Role) -> Self {
158 use crate::proto::member::Role::*;
159 match val {
160 Role::Unknown => Unknown,
161 Role::Default => Default,
162 Role::Administrator => Administrator,
163 }
164 .into()
165 }
166}
167
168impl TryFrom<i32> for AccessRequired {
169 type Error = GroupDecodingError;
170
171 fn try_from(value: i32) -> Result<Self, Self::Error> {
172 use crate::proto::access_control::AccessRequired::*;
173 match crate::proto::access_control::AccessRequired::try_from(value) {
174 Ok(Unknown) => Ok(AccessRequired::Unknown),
175 Ok(Any) => Ok(AccessRequired::Any),
176 Ok(Member) => Ok(AccessRequired::Member),
177 Ok(Administrator) => Ok(AccessRequired::Administrator),
178 Ok(Unsatisfiable) => Ok(AccessRequired::Unsatisfiable),
179 Err(_e) => Err(GroupDecodingError::WrongEnumValue),
180 }
181 }
182}
183
184impl From<AccessRequired> for i32 {
185 fn from(val: AccessRequired) -> Self {
186 use crate::proto::access_control::AccessRequired::*;
187 match val {
188 AccessRequired::Unknown => Unknown,
189 AccessRequired::Any => Any,
190 AccessRequired::Member => Member,
191 AccessRequired::Administrator => Administrator,
192 AccessRequired::Unsatisfiable => Unsatisfiable,
193 }
194 .into()
195 }
196}
197
198impl TryFrom<crate::proto::AccessControl> for AccessControl {
199 type Error = GroupDecodingError;
200
201 fn try_from(
202 value: crate::proto::AccessControl,
203 ) -> Result<Self, Self::Error> {
204 Ok(Self {
205 attributes: value.attributes.try_into()?,
206 members: value.members.try_into()?,
207 add_from_invite_link: value.add_from_invite_link.try_into()?,
208 })
209 }
210}