1pub mod events;
4
5use crate::Error;
6use serde::Deserialize;
7use std::{convert::TryFrom, fmt};
8
9pub type UserId = crate::types::Snowflake;
10
11#[derive(Clone)]
13pub struct Avatar(pub [u8; 16]);
14
15impl Avatar {
16 pub(crate) fn from_str(ava_str: &str) -> Option<Self> {
17 let avatar = ava_str.strip_prefix("a_").unwrap_or(ava_str);
18
19 if avatar.len() != 32 {
20 None
21 } else {
22 let mut md5 = [0u8; 16];
23
24 for (ind, exp) in avatar.as_bytes().chunks(2).enumerate() {
25 let mut cur = match exp[0] {
26 b'A'..=b'F' => exp[0] - b'A' + 10,
27 b'a'..=b'f' => exp[0] - b'a' + 10,
28 b'0'..=b'9' => exp[0] - b'0',
29 c => {
30 tracing::debug!("invalid character '{}' found in avatar", c);
31 return None;
32 }
33 };
34
35 cur <<= 4;
36
37 cur |= match exp[1] {
38 b'A'..=b'F' => exp[1] - b'A' + 10,
39 b'a'..=b'f' => exp[1] - b'a' + 10,
40 b'0'..=b'9' => exp[1] - b'0',
41 c => {
42 tracing::debug!("invalid character '{}' found in avatar", c);
43 return None;
44 }
45 };
46
47 md5[ind] = cur;
48 }
49
50 Some(Self(md5))
51 }
52 }
53}
54
55#[cfg(test)]
56impl serde::Serialize for Avatar {
57 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: serde::ser::Serializer,
60 {
61 use std::fmt::Write;
62 let mut hex_str = String::with_capacity(32);
63
64 for byte in self.0 {
65 let _ = write!(&mut hex_str, "{:02x}", byte);
66 }
67
68 serializer.serialize_str(&hex_str)
69 }
70}
71
72#[derive(Clone)]
76pub struct User {
77 pub id: UserId,
79 pub username: String,
81 pub discriminator: Option<u32>,
84 pub avatar: Option<Avatar>,
86 pub is_bot: bool,
88}
89
90impl<'de> Deserialize<'de> for User {
91 fn deserialize<D>(d: D) -> Result<Self, D::Error>
92 where
93 D: serde::de::Deserializer<'de>,
94 {
95 let u: DeUser<'de> = serde::de::Deserialize::deserialize(d)?;
96 Self::try_from(u).map_err(serde::de::Error::custom)
97 }
98}
99
100#[cfg(test)]
101impl serde::Serialize for User {
102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103 where
104 S: serde::ser::Serializer,
105 {
106 use serde::ser::SerializeStruct;
107
108 let mut state = serializer.serialize_struct("User", 5)?;
109 state.serialize_field("id", &self.id)?;
110 state.serialize_field("username", &self.username)?;
111 state.serialize_field(
112 "discriminator",
113 &self.discriminator.unwrap_or_default().to_string(),
114 )?;
115 state.serialize_field("avatar", &self.avatar)?;
116 state.serialize_field("bot", &self.is_bot)?;
117 state.end()
118 }
119}
120
121impl fmt::Debug for User {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.debug_struct("User")
124 .field("id", &self.id)
125 .field("username", &self.username)
126 .field("discriminator", &self.discriminator)
127 .finish()
128 }
129}
130
131impl fmt::Display for User {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 f.write_str(&self.username)?;
135
136 if let Some(disc) = self.discriminator {
137 write!(f, "#{}", disc)?;
138 }
139
140 Ok(())
141 }
142}
143
144#[derive(Deserialize)]
149struct DeUser<'u> {
150 id: Option<UserId>,
153 username: Option<&'u str>,
155 discriminator: Option<&'u str>,
158 avatar: Option<&'u str>,
160 bot: Option<bool>,
162}
163
164impl<'de> TryFrom<DeUser<'de>> for User {
165 type Error = Error;
166
167 fn try_from(u: DeUser<'de>) -> Result<Self, Self::Error> {
168 let id = u.id.ok_or(Error::MissingField("id"))?;
169 let username = u
170 .username
171 .ok_or(Error::MissingField("username"))?
172 .to_owned();
173
174 let discriminator = match u.discriminator {
176 Some(d) => Some(
177 d.parse()
178 .map_err(|_err| Error::InvalidField("discriminator"))?,
179 ),
180 None => None,
181 };
182 let avatar = match u.avatar {
184 Some(a) => Avatar::from_str(a),
185 None => None,
186 };
187
188 Ok(Self {
189 id,
190 username,
191 discriminator,
192 avatar,
193 is_bot: u.bot.unwrap_or(false),
194 })
195 }
196}