aboutsummaryrefslogtreecommitdiff
path: root/src/model/guild
diff options
context:
space:
mode:
Diffstat (limited to 'src/model/guild')
-rw-r--r--src/model/guild/emoji.rs4
-rw-r--r--src/model/guild/feature.rs25
-rw-r--r--src/model/guild/guild_id.rs24
-rw-r--r--src/model/guild/member.rs73
-rw-r--r--src/model/guild/mod.rs103
-rw-r--r--src/model/guild/partial_guild.rs9
-rw-r--r--src/model/guild/role.rs8
7 files changed, 128 insertions, 118 deletions
diff --git a/src/model/guild/emoji.rs b/src/model/guild/emoji.rs
index 4a2190f..7f332ae 100644
--- a/src/model/guild/emoji.rs
+++ b/src/model/guild/emoji.rs
@@ -151,8 +151,8 @@ impl Emoji {
/// ```
#[cfg(feature = "cache")]
pub fn find_guild_id(&self) -> Option<GuildId> {
- for guild in CACHE.read().unwrap().guilds.values() {
- let guild = guild.read().unwrap();
+ for guild in CACHE.read().guilds.values() {
+ let guild = guild.read();
if guild.emojis.contains_key(&self.id) {
return Some(guild.id);
diff --git a/src/model/guild/feature.rs b/src/model/guild/feature.rs
deleted file mode 100644
index 40fd3fd..0000000
--- a/src/model/guild/feature.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-/// A special feature, such as for VIP guilds, that a [`Guild`] has had granted
-/// to them.
-///
-/// [`Guild`]: struct.Guild.html
-#[derive(Copy, Clone, Debug, Deserialize, Hash, Eq, PartialEq)]
-pub enum Feature {
- /// The [`Guild`] can set a custom [`splash`][`Guild::splash`] image on
- /// invite URLs.
- ///
- /// [`Guild`]: struct.Guild.html
- /// [`Guild::splash`]: struct.Guild.html#structfield.splash
- #[serde(rename = "INVITE_SPLASH")]
- InviteSplash,
- /// The [`Guild`] can set a Vanity URL, which is a custom-named permanent
- /// invite code.
- ///
- /// [`Guild`]: struct.Guild.html
- #[serde(rename = "VANITY_URL")]
- VanityUrl,
- /// The [`Guild`] has access to VIP voice channel regions.
- ///
- /// [`Guild`]: struct.Guild.html
- #[serde(rename = "VIP_REGIONS")]
- VipRegions,
-}
diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs
index 622d059..7a851bb 100644
--- a/src/model/guild/guild_id.rs
+++ b/src/model/guild/guild_id.rs
@@ -5,11 +5,11 @@ use CACHE;
#[cfg(feature = "model")]
use builder::{EditGuild, EditMember, EditRole};
#[cfg(feature = "model")]
-use http;
-#[cfg(feature = "model")]
use internal::prelude::*;
#[cfg(feature = "model")]
use model::guild::BanOptions;
+#[cfg(feature = "model")]
+use {http, utils};
#[cfg(feature = "model")]
impl GuildId {
@@ -168,7 +168,9 @@ impl GuildId {
/// [Manage Roles]: permissions/constant.MANAGE_ROLES.html
#[inline]
pub fn create_role<F: FnOnce(EditRole) -> EditRole>(&self, f: F) -> Result<Role> {
- http::create_role(self.0, &f(EditRole::default()).0)
+ let map = utils::hashmap_to_json_map(f(EditRole::default()).0);
+
+ http::create_role(self.0, &map)
}
/// Deletes the current guild if the current account is the owner of the
@@ -229,7 +231,9 @@ impl GuildId {
/// [Manage Guild]: permissions/constant.MANAGE_GUILD.html
#[inline]
pub fn edit<F: FnOnce(EditGuild) -> EditGuild>(&mut self, f: F) -> Result<PartialGuild> {
- http::edit_guild(self.0, &f(EditGuild::default()).0)
+ let map = utils::hashmap_to_json_map(f(EditGuild::default()).0);
+
+ http::edit_guild(self.0, &map)
}
/// Edits an [`Emoji`]'s name in the guild.
@@ -266,7 +270,9 @@ impl GuildId {
#[inline]
pub fn edit_member<F, U>(&self, user_id: U, f: F) -> Result<()>
where F: FnOnce(EditMember) -> EditMember, U: Into<UserId> {
- http::edit_member(self.0, user_id.into().0, &f(EditMember::default()).0)
+ let map = utils::hashmap_to_json_map(f(EditMember::default()).0);
+
+ http::edit_member(self.0, user_id.into().0, &map)
}
/// Edits the current user's nickname for the guild.
@@ -300,7 +306,9 @@ impl GuildId {
#[inline]
pub fn edit_role<F, R>(&self, role_id: R, f: F) -> Result<Role>
where F: FnOnce(EditRole) -> EditRole, R: Into<RoleId> {
- http::edit_role(self.0, role_id.into().0, &f(EditRole::default()).0)
+ let map = utils::hashmap_to_json_map(f(EditRole::default()).0);
+
+ http::edit_role(self.0, role_id.into().0, &map)
}
/// Edits the order of [`Role`]s
@@ -326,7 +334,7 @@ impl GuildId {
/// Search the cache for the guild.
#[cfg(feature = "cache")]
- pub fn find(&self) -> Option<Arc<RwLock<Guild>>> { CACHE.read().unwrap().guild(*self) }
+ pub fn find(&self) -> Option<Arc<RwLock<Guild>>> { CACHE.read().guild(*self) }
/// Requests the guild over REST.
///
@@ -429,7 +437,7 @@ impl GuildId {
/// [`utils::shard_id`]: ../utils/fn.shard_id.html
#[cfg(all(feature = "cache", feature = "utils"))]
#[inline]
- pub fn shard_id(&self) -> u64 { ::utils::shard_id(self.0, CACHE.read().unwrap().shard_count) }
+ pub fn shard_id(&self) -> u64 { ::utils::shard_id(self.0, CACHE.read().shard_count) }
/// Returns the Id of the shard associated with the guild.
///
diff --git a/src/model/guild/member.rs b/src/model/guild/member.rs
index 83cb863..7420faa 100644
--- a/src/model/guild/member.rs
+++ b/src/model/guild/member.rs
@@ -6,15 +6,13 @@ use model::*;
#[cfg(feature = "model")]
use std::borrow::Cow;
#[cfg(all(feature = "cache", feature = "model"))]
-use CACHE;
-#[cfg(all(feature = "cache", feature = "model"))]
use internal::prelude::*;
-#[cfg(all(feature = "cache", feature = "model"))]
-use http;
#[cfg(all(feature = "builder", feature = "cache", feature = "model"))]
use builder::EditMember;
#[cfg(all(feature = "cache", feature = "model", feature = "utils"))]
use utils::Colour;
+#[cfg(all(feature = "cache", feature = "model"))]
+use {CACHE, http, utils};
pub trait BanOptions {
fn dmd(&self) -> u8 { 0 }
@@ -88,7 +86,7 @@ impl Member {
return Ok(());
}
- match http::add_member_role(self.guild_id.0, self.user.read().unwrap().id.0, role_id.0) {
+ match http::add_member_role(self.guild_id.0, self.user.read().id.0, role_id.0) {
Ok(()) => {
self.roles.push(role_id);
@@ -109,9 +107,10 @@ impl Member {
pub fn add_roles(&mut self, role_ids: &[RoleId]) -> Result<()> {
self.roles.extend_from_slice(role_ids);
- let map = EditMember::default().roles(&self.roles).0;
+ let builder = EditMember::default().roles(&self.roles);
+ let map = utils::hashmap_to_json_map(builder.0);
- match http::edit_member(self.guild_id.0, self.user.read().unwrap().id.0, &map) {
+ match http::edit_member(self.guild_id.0, self.user.read().id.0, &map) {
Ok(()) => Ok(()),
Err(why) => {
self.roles.retain(|r| !role_ids.contains(r));
@@ -149,7 +148,7 @@ impl Member {
http::ban_user(
self.guild_id.0,
- self.user.read().unwrap().id.0,
+ self.user.read().id.0,
dmd,
&*reason,
)
@@ -158,8 +157,8 @@ impl Member {
/// Determines the member's colour.
#[cfg(all(feature = "cache", feature = "utils"))]
pub fn colour(&self) -> Option<Colour> {
- let cache = CACHE.read().unwrap();
- let guild = try_opt!(cache.guilds.get(&self.guild_id)).read().unwrap();
+ let cache = CACHE.read();
+ let guild = try_opt!(cache.guilds.get(&self.guild_id)).read();
let mut roles = self.roles
.iter()
@@ -175,6 +174,27 @@ impl Member {
.map(|r| r.colour)
}
+ /// Returns the "default channel" of the guild for the member.
+ /// (This returns the first channel that can be read by the member, if there isn't
+ /// one returns `None`)
+ #[cfg(feature = "cache")]
+ pub fn default_channel(&self) -> Option<Arc<RwLock<GuildChannel>>> {
+ let guild = match self.guild_id.find() {
+ Some(guild) => guild,
+ None => return None,
+ };
+
+ let reader = guild.read();
+
+ for (cid, channel) in &reader.channels {
+ if reader.permissions_for(*cid, self.user.read().id).read_messages() {
+ return Some(channel.clone());
+ }
+ }
+
+ None
+ }
+
/// Calculates the member's display name.
///
/// The nickname takes priority over the member's username if it exists.
@@ -183,7 +203,7 @@ impl Member {
self.nick
.as_ref()
.map(Cow::Borrowed)
- .unwrap_or_else(|| Cow::Owned(self.user.read().unwrap().name.clone()))
+ .unwrap_or_else(|| Cow::Owned(self.user.read().name.clone()))
}
/// Returns the DiscordTag of a Member, taking possible nickname into account.
@@ -192,7 +212,7 @@ impl Member {
format!(
"{}#{}",
self.display_name(),
- self.user.read().unwrap().discriminator
+ self.user.read().discriminator
)
}
@@ -206,9 +226,9 @@ impl Member {
/// [`EditMember`]: ../builder/struct.EditMember.html
#[cfg(feature = "cache")]
pub fn edit<F: FnOnce(EditMember) -> EditMember>(&self, f: F) -> Result<()> {
- let map = f(EditMember::default()).0;
+ let map = utils::hashmap_to_json_map(f(EditMember::default()).0);
- http::edit_member(self.guild_id.0, self.user.read().unwrap().id.0, &map)
+ http::edit_member(self.guild_id.0, self.user.read().id.0, &map)
}
/// Kick the member from the guild.
@@ -251,17 +271,16 @@ impl Member {
let has_perms = CACHE
.read()
- .unwrap()
.guilds
.get(&self.guild_id)
- .map(|guild| guild.read().unwrap().has_perms(req));
+ .map(|guild| guild.read().has_perms(req));
if let Some(Ok(false)) = has_perms {
return Err(Error::Model(ModelError::InvalidPermissions(req)));
}
}
- self.guild_id.kick(self.user.read().unwrap().id)
+ self.guild_id.kick(self.user.read().id)
}
/// Returns the permissions for the member.
@@ -291,16 +310,18 @@ impl Member {
None => return Err(From::from(ModelError::GuildNotFound)),
};
- let guild = guild.read().unwrap();
+ let guild = guild.read();
- let default_channel = match guild.default_channel() {
+ let default_channel = match guild.default_channel(self.user.read().id) {
Some(dc) => dc,
None => return Err(From::from(ModelError::ItemMissing)),
};
+ let default_channel_reader = default_channel.read();
+
Ok(
guild
- .permissions_for(default_channel.id, self.user.read().unwrap().id),
+ .permissions_for(default_channel_reader.id, self.user.read().id),
)
}
@@ -319,7 +340,7 @@ impl Member {
return Ok(());
}
- match http::remove_member_role(self.guild_id.0, self.user.read().unwrap().id.0, role_id.0) {
+ match http::remove_member_role(self.guild_id.0, self.user.read().id.0, role_id.0) {
Ok(()) => {
self.roles.retain(|r| r.0 != role_id.0);
@@ -339,9 +360,10 @@ impl Member {
pub fn remove_roles(&mut self, role_ids: &[RoleId]) -> Result<()> {
self.roles.retain(|r| !role_ids.contains(r));
- let map = EditMember::default().roles(&self.roles).0;
+ let builder = EditMember::default().roles(&self.roles);
+ let map = utils::hashmap_to_json_map(builder.0);
- match http::edit_member(self.guild_id.0, self.user.read().unwrap().id.0, &map) {
+ match http::edit_member(self.guild_id.0, self.user.read().id.0, &map) {
Ok(()) => Ok(()),
Err(why) => {
self.roles.extend_from_slice(role_ids);
@@ -363,7 +385,6 @@ impl Member {
.find()
.map(|g| g
.read()
- .unwrap()
.roles
.values()
.filter(|role| self.roles.contains(&role.id))
@@ -385,7 +406,7 @@ impl Member {
/// [Ban Members]: permissions/constant.BAN_MEMBERS.html
#[cfg(feature = "cache")]
pub fn unban(&self) -> Result<()> {
- http::remove_ban(self.guild_id.0, self.user.read().unwrap().id.0)
+ http::remove_ban(self.guild_id.0, self.user.read().id.0)
}
}
@@ -401,6 +422,6 @@ impl Display for Member {
///
// This is in the format of `<@USER_ID>`.
fn fmt(&self, f: &mut Formatter) -> FmtResult {
- Display::fmt(&self.user.read().unwrap().mention(), f)
+ Display::fmt(&self.user.read().mention(), f)
}
}
diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs
index aa9fd1d..7aeb98f 100644
--- a/src/model/guild/mod.rs
+++ b/src/model/guild/mod.rs
@@ -1,5 +1,4 @@
mod emoji;
-mod feature;
mod guild_id;
mod integration;
mod member;
@@ -8,7 +7,6 @@ mod role;
mod audit_log;
pub use self::emoji::*;
-pub use self::feature::*;
pub use self::guild_id::*;
pub use self::integration::*;
pub use self::member::*;
@@ -21,7 +19,6 @@ use serde::de::Error as DeError;
use serde_json;
use super::utils::*;
use model::*;
-use std;
#[cfg(all(feature = "cache", feature = "model"))]
use CACHE;
@@ -31,6 +28,8 @@ use http;
use builder::{EditGuild, EditMember, EditRole};
#[cfg(feature = "model")]
use constants::LARGE_THRESHOLD;
+#[cfg(feature = "model")]
+use std;
/// A representation of a banning of a user.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash)]
@@ -62,8 +61,15 @@ pub struct Guild {
/// VIP features enabled for the guild. Can be obtained through the
/// [Discord Partnership] website.
///
+ /// The following is a list of known features:
+ ///
+ /// - `INVITE_SPLASH`
+ /// - `VANITY_URL`
+ /// - `VERIFIED`
+ /// - `VIP_REGIONS`
+ ///
/// [Discord Partnership]: https://discordapp.com/partners
- pub features: Vec<Feature>,
+ pub features: Vec<String>,
/// The hash of the icon used by the guild.
///
/// In the client, this appears on the guild list on the left-hand side.
@@ -124,16 +130,13 @@ pub struct Guild {
#[cfg(feature = "model")]
impl Guild {
- #[cfg(feature = "cache")]
- /// Returns the "default" channel of the guild.
- /// (This returns the first channel that can be read by the bot, if there isn't one,
+ /// Returns the "default" channel of the guild for the passed user id.
+ /// (This returns the first channel that can be read by the user, if there isn't one,
/// returns `None`)
- pub fn default_channel(&self) -> Option<GuildChannel> {
- let uid = CACHE.read().unwrap().user.id;
-
+ pub fn default_channel(&self, uid: UserId) -> Option<Arc<RwLock<GuildChannel>>> {
for (cid, channel) in &self.channels {
if self.permissions_for(*cid, uid).read_messages() {
- return Some(channel.read().unwrap().clone());
+ return Some(channel.clone());
}
}
@@ -145,11 +148,11 @@ impl Guild {
/// returns `None`)
/// Note however that this is very costy if used in a server with lots of channels,
/// members, or both.
- pub fn default_channel_guaranteed(&self) -> Option<GuildChannel> {
+ pub fn default_channel_guaranteed(&self) -> Option<Arc<RwLock<GuildChannel>>> {
for (cid, channel) in &self.channels {
for memid in self.members.keys() {
if self.permissions_for(*cid, *memid).read_messages() {
- return Some(channel.read().unwrap().clone());
+ return Some(channel.clone());
}
}
}
@@ -159,17 +162,17 @@ impl Guild {
#[cfg(feature = "cache")]
fn has_perms(&self, mut permissions: Permissions) -> Result<bool> {
- let member = match self.members.get(&CACHE.read().unwrap().user.id) {
+ let member = match self.members.get(&CACHE.read().user.id) {
Some(member) => member,
None => return Err(Error::Model(ModelError::ItemMissing)),
};
- let default_channel = match self.default_channel() {
+ let default_channel = match self.default_channel(member.user.read().id) {
Some(dc) => dc,
None => return Err(Error::Model(ModelError::ItemMissing)),
};
- let perms = self.permissions_for(default_channel.id, member.user.read().unwrap().id);
+ let perms = self.permissions_for(default_channel.read().id, member.user.read().id);
permissions.remove(perms);
Ok(permissions.is_empty())
@@ -410,7 +413,7 @@ impl Guild {
pub fn delete(&self) -> Result<PartialGuild> {
#[cfg(feature = "cache")]
{
- if self.owner_id != CACHE.read().unwrap().user.id {
+ if self.owner_id != CACHE.read().user.id {
let req = Permissions::MANAGE_GUILD;
return Err(Error::Model(ModelError::InvalidPermissions(req)));
@@ -747,9 +750,9 @@ impl Guild {
self.members
.values()
.find(|member| {
- let name_matches = member.user.read().unwrap().name == name;
+ let name_matches = member.user.read().name == name;
let discrim_matches = match discrim {
- Some(discrim) => member.user.read().unwrap().discriminator == discrim,
+ Some(discrim) => member.user.read().discriminator == discrim,
None => true,
};
@@ -764,11 +767,6 @@ impl Guild {
/// Retrieves all [`Member`] that start with a given `String`.
///
- /// If the prefix is "zey", following results are possible:
- /// - "zey", "zeyla", "zey mei"
- /// If 'case_sensitive' is false, the following are not found:
- /// - "Zey", "ZEYla", "zeY mei"
- ///
/// `sorted` decides whether the best early match of the `prefix`
/// should be the criteria to sort the result.
/// For the `prefix` "zey" and the unsorted result:
@@ -783,9 +781,9 @@ impl Guild {
.filter(|member|
if case_sensitive {
- member.user.read().unwrap().name.starts_with(prefix)
+ member.user.read().name.starts_with(prefix)
} else {
- starts_with_case_insensitive(&member.user.read().unwrap().name, prefix)
+ starts_with_case_insensitive(&member.user.read().name, prefix)
}
|| member.nick.as_ref()
@@ -802,24 +800,24 @@ impl Guild {
.sort_by(|a, b| {
let name_a = match a.nick {
Some(ref nick) => {
- if contains_case_insensitive(&a.user.read().unwrap().name[..], prefix) {
- a.user.read().unwrap().name.clone()
+ if contains_case_insensitive(&a.user.read().name[..], prefix) {
+ a.user.read().name.clone()
} else {
nick.clone()
}
},
- None => a.user.read().unwrap().name.clone(),
+ None => a.user.read().name.clone(),
};
let name_b = match b.nick {
Some(ref nick) => {
- if contains_case_insensitive(&b.user.read().unwrap().name[..], prefix) {
- b.user.read().unwrap().name.clone()
+ if contains_case_insensitive(&b.user.read().name[..], prefix) {
+ b.user.read().name.clone()
} else {
nick.clone()
}
},
- None => b.user.read().unwrap().name.clone(),
+ None => b.user.read().name.clone(),
};
closest_to_origin(prefix, &name_a[..], &name_b[..])
@@ -858,9 +856,9 @@ impl Guild {
.filter(|member|
if case_sensitive {
- member.user.read().unwrap().name.contains(substring)
+ member.user.read().name.contains(substring)
} else {
- contains_case_insensitive(&member.user.read().unwrap().name, substring)
+ contains_case_insensitive(&member.user.read().name, substring)
}
|| member.nick.as_ref()
@@ -878,24 +876,24 @@ impl Guild {
.sort_by(|a, b| {
let name_a = match a.nick {
Some(ref nick) => {
- if contains_case_insensitive(&a.user.read().unwrap().name[..], substring) {
- a.user.read().unwrap().name.clone()
+ if contains_case_insensitive(&a.user.read().name[..], substring) {
+ a.user.read().name.clone()
} else {
nick.clone()
}
},
- None => a.user.read().unwrap().name.clone(),
+ None => a.user.read().name.clone(),
};
let name_b = match b.nick {
Some(ref nick) => {
- if contains_case_insensitive(&b.user.read().unwrap().name[..], substring) {
- b.user.read().unwrap().name.clone()
+ if contains_case_insensitive(&b.user.read().name[..], substring) {
+ b.user.read().name.clone()
} else {
nick.clone()
}
},
- None => b.user.read().unwrap().name.clone(),
+ None => b.user.read().name.clone(),
};
closest_to_origin(substring, &name_a[..], &name_b[..])
@@ -927,17 +925,17 @@ impl Guild {
.values()
.filter(|member| {
if case_sensitive {
- member.user.read().unwrap().name.contains(substring)
+ member.user.read().name.contains(substring)
} else {
- contains_case_insensitive(&member.user.read().unwrap().name, substring)
+ contains_case_insensitive(&member.user.read().name, substring)
}
}).collect();
if sorted {
members
.sort_by(|a, b| {
- let name_a = &a.user.read().unwrap().name;
- let name_b = &b.user.read().unwrap().name;
+ let name_a = &a.user.read().name;
+ let name_b = &b.user.read().name;
closest_to_origin(substring, &name_a[..], &name_b[..])
});
members
@@ -986,14 +984,14 @@ impl Guild {
Some(ref nick) => {
nick.clone()
},
- None => a.user.read().unwrap().name.clone(),
+ None => a.user.read().name.clone(),
};
let name_b = match b.nick {
Some(ref nick) => {
nick.clone()
},
- None => b.user.read().unwrap().name.clone(),
+ None => b.user.read().name.clone(),
};
closest_to_origin(substring, &name_a[..], &name_b[..])
@@ -1057,7 +1055,7 @@ impl Guild {
} else {
warn!(
"(╯°□°)╯︵ ┻━┻ {} on {} has non-existent role {:?}",
- member.user.read().unwrap().id,
+ member.user.read().id,
self.id,
role
);
@@ -1070,7 +1068,7 @@ impl Guild {
}
if let Some(channel) = self.channels.get(&channel_id) {
- let channel = channel.read().unwrap();
+ let channel = channel.read();
// If this is a text channel, then throw out voice permissions.
if channel.kind == ChannelType::Text {
@@ -1308,9 +1306,9 @@ impl Guild {
/// use serenity::CACHE;
///
/// impl EventHandler for Handler {
- /// fn on_message(&self, _: Context, msg: Message) {
+ /// fn message(&self, _: Context, msg: Message) {
/// if let Some(arc) = msg.guild_id().unwrap().find() {
- /// if let Some(role) = arc.read().unwrap().role_by_name("role_name") {
+ /// if let Some(role) = arc.read().role_by_name("role_name") {
/// println!("{:?}", role);
/// }
/// }
@@ -1379,7 +1377,7 @@ impl<'de> Deserialize<'de> for Guild {
.map_err(DeError::custom)?;
let features = map.remove("features")
.ok_or_else(|| DeError::custom("expected guild features"))
- .and_then(serde_json::from_value::<Vec<Feature>>)
+ .and_then(serde_json::from_value::<Vec<String>>)
.map_err(DeError::custom)?;
let icon = match map.remove("icon") {
Some(v) => Option::<String>::deserialize(v).map_err(DeError::custom)?,
@@ -1469,11 +1467,13 @@ impl<'de> Deserialize<'de> for Guild {
}
/// Checks if a `&str` contains another `&str`.
+#[cfg(feature = "model")]
fn contains_case_insensitive(to_look_at: &str, to_find: &str) -> bool {
to_look_at.to_lowercase().contains(to_find)
}
/// Checks if a `&str` starts with another `&str`.
+#[cfg(feature = "model")]
fn starts_with_case_insensitive(to_look_at: &str, to_find: &str) -> bool {
to_look_at.to_lowercase().starts_with(to_find)
}
@@ -1485,6 +1485,7 @@ fn starts_with_case_insensitive(to_look_at: &str, to_find: &str) -> bool {
/// expected to contain `origin` as substring.
/// If not, using `closest_to_origin` would sort these
/// the end.
+#[cfg(feature = "model")]
fn closest_to_origin(origin: &str, word_a: &str, word_b: &str) -> std::cmp::Ordering {
let value_a = match word_a.find(origin) {
Some(value) => value + word_a.len(),
diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs
index cb2f8ef..bdfcbe0 100644
--- a/src/model/guild/partial_guild.rs
+++ b/src/model/guild/partial_guild.rs
@@ -17,7 +17,12 @@ pub struct PartialGuild {
pub embed_channel_id: Option<ChannelId>,
pub embed_enabled: bool,
#[serde(deserialize_with = "deserialize_emojis")] pub emojis: HashMap<EmojiId, Emoji>,
- pub features: Vec<Feature>,
+ /// Features enabled for the guild.
+ ///
+ /// Refer to [`Guild::features`] for more information.
+ ///
+ /// [`Guild::features`]: struct.Guild.html#structfield.features
+ pub features: Vec<String>,
pub icon: Option<String>,
pub mfa_level: u64,
pub name: String,
@@ -451,7 +456,7 @@ impl PartialGuild {
/// use serenity::CACHE;
///
/// impl EventHandler for Handler {
- /// fn on_message(&self, _: Context, msg: Message) {
+ /// fn message(&self, _: Context, msg: Message) {
/// if let Some(role) =
/// msg.guild_id().unwrap().get().unwrap().role_by_name("role_name") {
/// println!("Obtained role's reference: {:?}", role);
diff --git a/src/model/guild/role.rs b/src/model/guild/role.rs
index 7ac7019..3ed718e 100644
--- a/src/model/guild/role.rs
+++ b/src/model/guild/role.rs
@@ -106,8 +106,8 @@ impl Role {
/// [`ModelError::GuildNotFound`]: enum.ModelError.html#variant.GuildNotFound
#[cfg(feature = "cache")]
pub fn find_guild(&self) -> Result<GuildId> {
- for guild in CACHE.read().unwrap().guilds.values() {
- let guild = guild.read().unwrap();
+ for guild in CACHE.read().guilds.values() {
+ let guild = guild.read();
if guild.roles.contains_key(&RoleId(self.id.0)) {
return Ok(guild.id);
@@ -168,10 +168,10 @@ impl RoleId {
/// Search the cache for the role.
#[cfg(feature = "cache")]
pub fn find(&self) -> Option<Role> {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
for guild in cache.guilds.values() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
if !guild.roles.contains_key(self) {
continue;