aboutsummaryrefslogtreecommitdiff
path: root/src/model/user.rs
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-09-19 09:00:03 -0700
committerAustin Hellyer <[email protected]>2016-10-18 11:14:27 -0700
commit8fc8c81403c3daa187ba96a7d488a64db21463bf (patch)
tree81bc4890c28b08ce806f69084617066bce863c2d /src/model/user.rs
downloadserenity-8fc8c81403c3daa187ba96a7d488a64db21463bf.tar.xz
serenity-8fc8c81403c3daa187ba96a7d488a64db21463bf.zip
Initial commit
Diffstat (limited to 'src/model/user.rs')
-rw-r--r--src/model/user.rs146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/model/user.rs b/src/model/user.rs
new file mode 100644
index 0000000..cb235ab
--- /dev/null
+++ b/src/model/user.rs
@@ -0,0 +1,146 @@
+use serde_json::builder::ObjectBuilder;
+use std::fmt;
+use super::utils::{into_map, into_string, remove, warn_field};
+use super::{
+ FriendSourceFlags,
+ GuildContainer,
+ GuildId,
+ Mention,
+ Message,
+ RoleId,
+ UserSettings,
+ User
+};
+use ::client::{STATE, http};
+use ::prelude::*;
+use ::utils::decode_array;
+
+impl User {
+ /// Returns the formatted URL of the user's icon, if one exists.
+ pub fn avatar_url(&self) -> Option<String> {
+ self.avatar.as_ref().map(|av|
+ format!(cdn_concat!("/avatars/{}/{}.jpg"), self.id, av))
+ }
+
+ /// This is an alias of [direct_message].
+ ///
+ /// [direct_message]: #method.direct_message
+ pub fn dm(&self, content: &str) -> Result<Message> {
+ self.direct_message(content)
+ }
+
+ /// Send a direct message to a user. This will create or retrieve the
+ /// PrivateChannel over REST if one is not already in the State, and then
+ /// send a message to it.
+ pub fn direct_message(&self, content: &str)
+ -> Result<Message> {
+ let private_channel_id = {
+ let finding = STATE.lock()
+ .unwrap()
+ .private_channels
+ .values()
+ .find(|ch| ch.recipient.id == self.id)
+ .map(|ch| ch.id);
+
+ if let Some(finding) = finding {
+ finding
+ } else {
+ let map = ObjectBuilder::new()
+ .insert("recipient_id", self.id.0)
+ .build();
+
+ try!(http::create_private_channel(map)).id
+ }
+ };
+
+ let map = ObjectBuilder::new()
+ .insert("content", content)
+ .insert("nonce", "")
+ .insert("tts", false)
+ .build();
+
+ http::send_message(private_channel_id.0, map)
+ }
+
+ /// Check if a user has a [`Role`]. This will retrieve the
+ /// [`Guild`] from the [`State`] if
+ /// it is available, and then check if that guild has the given [`Role`].
+ ///
+ /// If the [`Guild`] is not present, then the guild will be retrieved from
+ /// the API and the state will be updated with it.
+ ///
+ /// If there are issues with requesting the API, then `false` will be
+ /// returned.
+ ///
+ /// Three forms of data may be passed in to the guild parameter: either a
+ /// [`Guild`] itself, a [`GuildId`], or a `u64`.
+ ///
+ /// # Examples
+ ///
+ /// Check if a guild has a [`Role`] by Id:
+ ///
+ /// ```rust,ignore
+ /// // Assumes a 'guild' and `role_id` have already been defined
+ /// context.message.author.has_role(guild, role_id);
+ /// ```
+ ///
+ /// [`Guild`]: struct.Guild.html
+ /// [`GuildId`]: struct.GuildId.html
+ /// [`Role`]: struct.Role.html
+ /// [`State`]: ../ext/state/struct.State.html
+ pub fn has_role<G, R>(&self, guild: G, role: R) -> bool
+ where G: Into<GuildContainer>, R: Into<RoleId> {
+ let role_id = role.into();
+
+ match guild.into() {
+ GuildContainer::Guild(guild) => {
+ guild.find_role(role_id).is_some()
+ },
+ GuildContainer::Id(guild_id) => {
+ let state = STATE.lock().unwrap();
+
+ state.find_role(guild_id, role_id).is_some()
+ },
+ }
+ }
+
+ /// Return a [`Mention`] which will ping this user.
+ ///
+ /// [`Mention`]: struct.Mention.html
+ pub fn mention(&self) -> Mention {
+ self.id.mention()
+ }
+}
+
+impl fmt::Display for User {
+ /// Formats a string which will mention the user.
+ // This is in the format of: `<@USER_ID>`
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.id.mention(), f)
+ }
+}
+
+impl UserSettings {
+ #[doc(hidden)]
+ pub fn decode(value: Value) -> Result<Option<UserSettings>> {
+ let mut map = try!(into_map(value));
+
+ if map.is_empty() {
+ return Ok(None);
+ }
+
+ missing!(map, UserSettings {
+ convert_emoticons: req!(try!(remove(&mut map, "convert_emoticons")).as_bool()),
+ enable_tts_command: req!(try!(remove(&mut map, "enable_tts_command")).as_bool()),
+ friend_source_flags: try!(remove(&mut map, "friend_source_flags").and_then(FriendSourceFlags::decode)),
+ inline_attachment_media: req!(try!(remove(&mut map, "inline_attachment_media")).as_bool()),
+ inline_embed_media: req!(try!(remove(&mut map, "inline_embed_media")).as_bool()),
+ locale: try!(remove(&mut map, "locale").and_then(into_string)),
+ message_display_compact: req!(try!(remove(&mut map, "message_display_compact")).as_bool()),
+ render_embeds: req!(try!(remove(&mut map, "render_embeds")).as_bool()),
+ restricted_guilds: try!(remove(&mut map, "restricted_guilds").and_then(|v| decode_array(v, GuildId::decode))),
+ show_current_game: req!(try!(remove(&mut map, "show_current_game")).as_bool()),
+ theme: try!(remove(&mut map, "theme").and_then(into_string)),
+ }).map(Some)
+ }
+}