1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::{Map, Value};
4#[cfg(feature = "sqlx")]
5use sqlx::{FromRow, Type};
6
7use crate::{
8 errors::Error,
9 utils::Snowflake, };
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13#[cfg_attr(feature = "sqlx", derive(FromRow))]
14pub struct User {
15 pub id: Snowflake,
16 pub username: String,
17 pub discriminator: String,
18 pub avatar: Option<String>,
19 pub accent_color: Option<u8>,
20 pub banner: Option<String>,
21 pub theme_colors: Option<Vec<u8>>,
22 pub pronouns: Option<String>,
23 pub phone: Option<String>,
24 pub desktop: bool,
25 pub mobile: bool,
26 pub premium: bool,
27 pub premium_type: u8,
28 pub bot: bool,
29 pub bio: String,
30 pub system: bool,
31 pub nsfw_allowed: bool,
32 pub mfa_enabled: bool,
33 pub webauthn_enabled: bool,
34 #[serde(skip)]
35 pub totp_secret: Option<String>,
36 #[serde(skip)]
37 pub totp_last_ticket: Option<String>,
38 pub created_at: DateTime<Utc>,
39 pub premium_since: Option<DateTime<Utc>>,
40 pub verified: bool,
41 pub disabled: bool,
42 pub deleted: bool,
43 pub email: Option<String>,
44 pub flags: String,
45 pub public_flags: u16,
46 pub purchased_flags: u16,
47 pub premium_usage_flags: u16,
48 pub rights: String,
49 #[cfg(feature = "sqlx")]
50 pub relationship_ids: sqlx::types::Json<Vec<String>>,
51 #[cfg(not(feature = "sqlx"))]
52 pub relationship_ids: Vec<String>,
53 #[cfg(feature = "sqlx")]
54 pub connected_account_ids: sqlx::types::Json<Vec<String>>,
55 #[cfg(not(feature = "sqlx"))]
56 pub connected_account_ids: Vec<String>,
57 #[cfg(feature = "sqlx")]
58 pub data: sqlx::types::Json<UserData>,
59 #[cfg(not(feature = "sqlx"))]
60 pub data: UserData,
61 #[cfg(feature = "sqlx")]
62 pub fingerprints: sqlx::types::Json<Vec<String>>,
63 #[cfg(not(feature = "sqlx"))]
64 pub fingerprints: Vec<String>,
65 pub extended_settings: Value,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
70#[cfg_attr(feature = "sqlx", derive(Type))]
71pub struct UserData {
72 pub valid_tokens_since: DateTime<Utc>,
73 pub hash: Option<String>,
74}
75
76impl Default for User {
77 fn default() -> Self {
78 Self {
79 id: Snowflake::generate(),
80 username: String::new(),
81 discriminator: String::new(),
82 avatar: None,
83 accent_color: None,
84 banner: None,
85 theme_colors: None,
86 pronouns: None,
87 phone: None,
88 desktop: false,
89 mobile: false,
90 premium: false,
91 premium_type: 0,
92 bot: false,
93 bio: String::new(),
94 system: false,
95 nsfw_allowed: false,
96 mfa_enabled: false,
97 webauthn_enabled: false,
98 totp_secret: None,
99 totp_last_ticket: None,
100 created_at: Utc::now(),
101 premium_since: None,
102 verified: false,
103 disabled: false,
104 deleted: false,
105 email: None,
106 flags: String::from("0"),
107 public_flags: 0,
108 purchased_flags: 0,
109 premium_usage_flags: 0,
110 rights: String::new(),
111 relationship_ids: Default::default(),
112 connected_account_ids: Default::default(),
113 data: Default::default(),
114 fingerprints: Default::default(),
115 extended_settings: Value::Object(Map::new()),
117 }
118 }
119}
120
121impl User {
122 pub fn validate(&mut self) -> Result<(), Error> {
123 todo!()
132 }
133
134 pub async fn generate_discriminator(_username: &str) -> Result<String, Error> {
135 todo!()
136 }
137}
138
139impl User {
140 pub fn to_public_user(self) -> PublicUser {
141 PublicUser::from(self)
142 }
143}
144
145#[derive(Serialize, Deserialize, Debug, Default, Clone)]
146pub struct PrivateUser {
147 pub id: String,
148 username: String,
149 discriminator: String,
150 avatar: Option<String>,
151 bot: bool,
152 system: Option<bool>,
153 mfa_enabled: Option<bool>,
154 accent_color: Option<String>,
155 locale: Option<String>,
156 verified: Option<bool>,
157 email: Option<String>,
158 flags: String,
159 premium_since: Option<String>,
160 premium_type: i8,
161 pronouns: Option<String>,
162 public_flags: Option<i8>,
163 banner: Option<String>,
164 bio: String,
165 theme_colors: Option<Vec<i32>>,
166 phone: Option<String>,
167 nsfw_allowed: bool,
168 premium: bool,
169 purchased_flags: i32,
170 premium_usage_flags: i32,
171 disabled: Option<bool>,
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
175pub struct PublicUser {
176 pub id: Snowflake,
177 pub username: String,
178 pub discriminator: String,
179 pub avatar: Option<String>,
180 pub accent_color: Option<u8>,
181 pub banner: Option<String>,
182 pub theme_colors: Option<Vec<u8>>,
183 pub pronouns: Option<String>,
184 pub bot: bool,
185 pub bio: String,
186 pub premium_type: u8,
187 pub premium_since: Option<DateTime<Utc>>,
188 pub public_flags: u16,
189}
190
191impl From<User> for PublicUser {
192 fn from(value: User) -> Self {
193 Self {
194 id: value.id,
195 username: value.username,
196 discriminator: value.discriminator,
197 avatar: value.avatar,
198 accent_color: value.accent_color,
199 banner: value.banner,
200 theme_colors: value.theme_colors,
201 pronouns: value.pronouns,
202 bot: value.bot,
203 bio: value.bio,
204 premium_type: value.premium_type,
205 premium_since: value.premium_since,
206 public_flags: value.public_flags,
207 }
208 }
209}
210
211const CUSTOM_USER_FLAG_OFFSET: u64 = 1 << 32;
212
213bitflags::bitflags! {
214 #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
215 #[cfg_attr(feature = "sqlx", derive(Type))]
216 pub struct UserFlags: u64 {
217 const DISCORD_EMPLOYEE = 1 << 0;
218 const PARTNERED_SERVER_OWNER = 1 << 1;
219 const HYPESQUAD_EVENTS = 1 << 2;
220 const BUGHUNTER_LEVEL_1 =1 << 3;
221 const MFA_SMS = 1 << 4;
222 const PREMIUM_PROMO_DISMISSED = 1 << 5;
223 const HOUSE_BRAVERY = 1 << 6;
224 const HOUSE_BRILLIANCE = 1 << 7;
225 const HOUSE_BALANCE = 1 << 8;
226 const EARLY_SUPPORTER = 1 << 9;
227 const TEAM_USER = 1 << 10;
228 const TRUST_AND_SAFETY = 1 << 11;
229 const SYSTEM = 1 << 12;
230 const HAS_UNREAD_URGENT_MESSAGES = 1 << 13;
231 const BUGHUNTER_LEVEL_2 = 1 << 14;
232 const UNDERAGE_DELETED = 1 << 15;
233 const VERIFIED_BOT = 1 << 16;
234 const EARLY_VERIFIED_BOT_DEVELOPER = 1 << 17;
235 const CERTIFIED_MODERATOR = 1 << 18;
236 const BOT_HTTP_INTERACTIONS = 1 << 19;
237 }
238}