aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-10-10 20:08:11 -0700
committerZeyla Hellyer <[email protected]>2017-10-10 20:08:11 -0700
commit93e0a4215c915b98cf433ac6d0bcfbc60f0168ec (patch)
tree727111506d1f89cd8a511b8b79c102131222421f /src
parentResume on resumable session invalidations (diff)
downloadserenity-93e0a4215c915b98cf433ac6d0bcfbc60f0168ec.tar.xz
serenity-93e0a4215c915b98cf433ac6d0bcfbc60f0168ec.zip
Switch to parking_lot::{Mutex, RwLock}
Switch to the `parking_lot` crate's implementations of `std::sync::Mutex` and `std::sync::RwLock`, which are more efficient. A writeup on why `parking_lot` is more efficient can be read here: <https://github.com/Amanieu/parking_lot> Upgrade path: Modify `mutex.lock().unwrap()` usage to `mutex.lock()` (not needing to unwrap or handle a result), and `rwlock.read().unwrap()`/`rwlock.write().unwrap()` usage to `rwlock.read()` and `rwlock.write()`. For example, modify: ```rust use serenity::CACHE; println!("{}", CACHE.read().unwrap().user.id); ``` to: ```rust use serenity::CACHE; println!("{}", CACHE.read().user.id); ```
Diffstat (limited to 'src')
-rw-r--r--src/builder/create_embed.rs10
-rw-r--r--src/builder/create_invite.rs20
-rw-r--r--src/cache/mod.rs50
-rw-r--r--src/client/bridge/gateway/shard_manager.rs14
-rw-r--r--src/client/bridge/gateway/shard_queuer.rs10
-rw-r--r--src/client/bridge/gateway/shard_runner.rs10
-rw-r--r--src/client/context.rs2
-rw-r--r--src/client/dispatch.rs18
-rw-r--r--src/client/event_handler.rs3
-rw-r--r--src/client/mod.rs16
-rw-r--r--src/framework/standard/help_commands.rs14
-rw-r--r--src/framework/standard/mod.rs5
-rw-r--r--src/gateway/shard.rs165
-rw-r--r--src/http/mod.rs11
-rw-r--r--src/http/ratelimiting.rs16
-rw-r--r--src/internal/rwlock_ext.rs13
-rw-r--r--src/lib.rs14
-rw-r--r--src/model/channel/channel_id.rs12
-rw-r--r--src/model/channel/guild_channel.rs22
-rw-r--r--src/model/channel/message.rs26
-rw-r--r--src/model/channel/mod.rs18
-rw-r--r--src/model/channel/private_channel.rs2
-rw-r--r--src/model/channel/reaction.rs2
-rw-r--r--src/model/event.rs39
-rw-r--r--src/model/gateway.rs3
-rw-r--r--src/model/guild/emoji.rs4
-rw-r--r--src/model/guild/guild_id.rs4
-rw-r--r--src/model/guild/member.rs47
-rw-r--r--src/model/guild/mod.rs34
-rw-r--r--src/model/guild/role.rs8
-rw-r--r--src/model/mod.rs5
-rw-r--r--src/model/user.rs67
-rw-r--r--src/model/utils.rs18
-rw-r--r--src/utils/mod.rs4
-rw-r--r--src/voice/connection.rs15
35 files changed, 401 insertions, 320 deletions
diff --git a/src/builder/create_embed.rs b/src/builder/create_embed.rs
index a6b264c..f7dc0b1 100644
--- a/src/builder/create_embed.rs
+++ b/src/builder/create_embed.rs
@@ -249,20 +249,20 @@ impl CreateEmbed {
/// impl EventHandler for Handler {
/// fn on_guild_member_addition(&self, _: Context, guild_id: GuildId, member: Member) {
/// use serenity::client::CACHE;
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
///
/// if let Some(guild) = cache.guild(guild_id) {
- /// let guild = guild.read().unwrap();
+ /// let guild = guild.read();
///
/// let channel_search = guild
/// .channels
/// .values()
- /// .find(|c| c.read().unwrap().name == "join-log");
+ /// .find(|c| c.read().name == "join-log");
///
/// if let Some(channel) = channel_search {
- /// let user = member.user.read().unwrap();
+ /// let user = member.user.read();
///
- /// let _ = channel.read().unwrap().send_message(|m| m
+ /// let _ = channel.read().send_message(|m| m
/// .embed(|e| {
/// let mut e = e
/// .author(|a| a.icon_url(&user.face()).name(&user.name))
diff --git a/src/builder/create_invite.rs b/src/builder/create_invite.rs
index 5f4f0bf..d719c17 100644
--- a/src/builder/create_invite.rs
+++ b/src/builder/create_invite.rs
@@ -21,7 +21,7 @@ use internal::prelude::*;
/// fn on_message(&self, _: Context, msg: Message) {
/// use serenity::client::CACHE;
/// if msg.content == "!createinvite" {
-/// let channel = match CACHE.read().unwrap().guild_channel(msg.channel_id) {
+/// let channel = match CACHE.read().guild_channel(msg.channel_id) {
/// Some(channel) => channel,
/// None => {
/// let _ = msg.channel_id.say("Error creating invite");
@@ -30,7 +30,7 @@ use internal::prelude::*;
/// },
/// };
///
-/// let reader = channel.read().unwrap();
+/// let reader = channel.read();
///
/// let invite = match reader.create_invite(|i| i.max_age(3600).max_uses(10)) {
/// Ok(invite) => invite,
@@ -77,8 +77,8 @@ impl CreateInvite {
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
- /// # let channel = CACHE.read().unwrap().guild_channel(81384788765712384).unwrap();
- /// # let channel = channel.read().unwrap();
+ /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap();
+ /// # let channel = channel.read();
/// #
/// let invite = channel.create_invite(|i| i.max_age(3600))?;
/// # Ok(())
@@ -111,8 +111,8 @@ impl CreateInvite {
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
- /// # let channel = CACHE.read().unwrap().guild_channel(81384788765712384).unwrap();
- /// # let channel = channel.read().unwrap();
+ /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap();
+ /// # let channel = channel.read();
/// #
/// let invite = channel.create_invite(|i| i.max_uses(5))?;
/// # Ok(())
@@ -143,8 +143,8 @@ impl CreateInvite {
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
- /// # let channel = CACHE.read().unwrap().guild_channel(81384788765712384).unwrap();
- /// # let channel = channel.read().unwrap();
+ /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap();
+ /// # let channel = channel.read();
/// #
/// let invite = channel.create_invite(|i| i.temporary(true))?;
/// # Ok(())
@@ -175,8 +175,8 @@ impl CreateInvite {
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
- /// # let channel = CACHE.read().unwrap().guild_channel(81384788765712384).unwrap();
- /// # let channel = channel.read().unwrap();
+ /// # let channel = CACHE.read().guild_channel(81384788765712384).unwrap();
+ /// # let channel = channel.read();
/// #
/// let invite = channel.create_invite(|i| i.unique(true))?;
/// # Ok(())
diff --git a/src/cache/mod.rs b/src/cache/mod.rs
index 9b43804..6b93d41 100644
--- a/src/cache/mod.rs
+++ b/src/cache/mod.rs
@@ -41,10 +41,12 @@
//! [`Role`]: ../model/struct.Role.html
//! [`CACHE`]: ../struct.CACHE.html
//! [`http`]: ../http/index.html
+
+use parking_lot::RwLock;
use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::default::Default;
-use std::sync::{Arc, RwLock};
+use std::sync::Arc;
use model::*;
mod cache_update;
@@ -188,7 +190,7 @@ impl Cache {
/// // seconds.
/// thread::sleep(Duration::from_secs(5));
///
- /// println!("{} unknown members", CACHE.read().unwrap().unknown_members());
+ /// println!("{} unknown members", CACHE.read().unknown_members());
/// }
/// }
///
@@ -202,7 +204,7 @@ impl Cache {
let mut total = 0;
for guild in self.guilds.values() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
let members = guild.members.len() as u64;
@@ -227,7 +229,7 @@ impl Cache {
/// ```rust,no_run
/// use serenity::client::CACHE;
///
- /// let amount = CACHE.read().unwrap().all_private_channels().len();
+ /// let amount = CACHE.read().all_private_channels().len();
///
/// println!("There are {} private channels", amount);
/// ```
@@ -260,7 +262,7 @@ impl Cache {
/// struct Handler;
/// impl EventHandler for Handler {
/// fn on_ready(&self, _: Context, _: Ready) {
- /// println!("Guilds in the Cache: {:?}", CACHE.read().unwrap().all_guilds());
+ /// println!("Guilds in the Cache: {:?}", CACHE.read().all_guilds());
/// }
/// }
/// let mut client = Client::new("token", Handler);
@@ -332,10 +334,8 @@ impl Cache {
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::client::CACHE;
///
- /// let cache = CACHE.read()?;
- ///
- /// if let Some(guild) = cache.guild(7) {
- /// println!("Guild name: {}", guild.read().unwrap().name);
+ /// if let Some(guild) = CACHE.read().guild(7) {
+ /// println!("Guild name: {}", guild.read().name);
/// }
/// # Ok(())
/// # }
@@ -370,7 +370,7 @@ impl Cache {
///
/// impl EventHandler for Handler {
/// fn on_message(&self, ctx: Context, message: Message) {
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
///
/// let channel = match cache.guild_channel(message.channel_id) {
/// Some(channel) => channel,
@@ -417,10 +417,8 @@ impl Cache {
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::client::CACHE;
///
- /// let cache = CACHE.read()?;
- ///
- /// if let Some(group) = cache.group(7) {
- /// println!("Owner Id: {}", group.read().unwrap().owner_id);
+ /// if let Some(group) = CACHE.read().group(7) {
+ /// println!("Owner Id: {}", group.read().owner_id);
/// }
/// # Ok(())
/// # }
@@ -448,7 +446,7 @@ impl Cache {
/// ```rust,ignore
/// use serenity::CACHE;
///
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
/// let member = {
/// let channel = match cache.guild_channel(message.channel_id) {
/// Some(channel) => channel,
@@ -482,7 +480,7 @@ impl Cache {
pub fn member<G, U>(&self, guild_id: G, user_id: U) -> Option<Member>
where G: Into<GuildId>, U: Into<UserId> {
self.guilds.get(&guild_id.into()).and_then(|guild| {
- guild.read().unwrap().members.get(&user_id.into()).cloned()
+ guild.read().members.get(&user_id.into()).cloned()
})
}
@@ -502,10 +500,8 @@ impl Cache {
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::client::CACHE;
///
- /// let cache = CACHE.read()?;
- ///
- /// if let Some(channel) = cache.private_channel(7) {
- /// channel.read().unwrap().say("Hello there!");
+ /// if let Some(channel) = CACHE.read().private_channel(7) {
+ /// channel.read().say("Hello there!");
/// }
/// # Ok(())
/// # }
@@ -539,9 +535,7 @@ impl Cache {
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::client::CACHE;
///
- /// let cache = CACHE.read()?;
- ///
- /// if let Some(role) = cache.role(7, 77) {
+ /// if let Some(role) = CACHE.read().role(7, 77) {
/// println!("Role with Id 77 is called {}", role.name);
/// }
/// # Ok(())
@@ -555,7 +549,7 @@ impl Cache {
where G: Into<GuildId>, R: Into<RoleId> {
self.guilds
.get(&guild_id.into())
- .and_then(|g| g.read().unwrap().roles.get(&role_id.into()).cloned())
+ .and_then(|g| g.read().roles.get(&role_id.into()).cloned())
}
/// Retrieves a `User` from the cache's [`users`] map, if it exists.
@@ -576,10 +570,8 @@ impl Cache {
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::client::CACHE;
///
- /// let cache = CACHE.read()?;
- ///
- /// if let Some(user) = cache.user(7) {
- /// println!("User with Id 7 is currently named {}", user.read().unwrap().name);
+ /// if let Some(user) = CACHE.read().user(7) {
+ /// println!("User with Id 7 is currently named {}", user.read().name);
/// }
/// # Ok(())
/// # }
@@ -611,7 +603,7 @@ impl Cache {
e.insert(Arc::new(RwLock::new(user.clone())));
},
Entry::Occupied(mut e) => {
- e.get_mut().write().unwrap().clone_from(user);
+ e.get_mut().write().clone_from(user);
},
}
}
diff --git a/src/client/bridge/gateway/shard_manager.rs b/src/client/bridge/gateway/shard_manager.rs
index 2068bef..4a50b56 100644
--- a/src/client/bridge/gateway/shard_manager.rs
+++ b/src/client/bridge/gateway/shard_manager.rs
@@ -1,8 +1,8 @@
use internal::prelude::*;
-use parking_lot::Mutex as ParkingLotMutex;
+use parking_lot::Mutex;
use std::collections::HashMap;
use std::sync::mpsc::{self, Receiver, Sender};
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::thread;
use super::super::super::EventHandler;
use super::{
@@ -19,7 +19,7 @@ use typemap::ShareMap;
use framework::Framework;
pub struct ShardManager {
- pub runners: Arc<ParkingLotMutex<HashMap<ShardId, ShardRunnerInfo>>>,
+ pub runners: Arc<Mutex<HashMap<ShardId, ShardRunnerInfo>>>,
/// The index of the first shard to initialize, 0-indexed.
shard_index: u64,
/// The number of shards to initialize.
@@ -38,7 +38,7 @@ impl ShardManager {
shard_total: u64,
ws_url: Arc<Mutex<String>>,
token: Arc<Mutex<String>>,
- data: Arc<ParkingLotMutex<ShareMap>>,
+ data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>,
framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
threadpool: ThreadPool,
@@ -46,7 +46,7 @@ impl ShardManager {
let (thread_tx, thread_rx) = mpsc::channel();
let (shard_queue_tx, shard_queue_rx) = mpsc::channel();
- let runners = Arc::new(ParkingLotMutex::new(HashMap::new()));
+ let runners = Arc::new(Mutex::new(HashMap::new()));
let mut shard_queuer = ShardQueuer {
data: data.clone(),
@@ -82,14 +82,14 @@ impl ShardManager {
shard_total: u64,
ws_url: Arc<Mutex<String>>,
token: Arc<Mutex<String>>,
- data: Arc<ParkingLotMutex<ShareMap>>,
+ data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>,
threadpool: ThreadPool,
) -> Self where H: EventHandler + Send + Sync + 'static {
let (thread_tx, thread_rx) = mpsc::channel();
let (shard_queue_tx, shard_queue_rx) = mpsc::channel();
- let runners = Arc::new(ParkingLotMutex::new(HashMap::new()));
+ let runners = Arc::new(Mutex::new(HashMap::new()));
let mut shard_queuer = ShardQueuer {
data: data.clone(),
diff --git a/src/client/bridge/gateway/shard_queuer.rs b/src/client/bridge/gateway/shard_queuer.rs
index ea49de4..f75e35d 100644
--- a/src/client/bridge/gateway/shard_queuer.rs
+++ b/src/client/bridge/gateway/shard_queuer.rs
@@ -1,9 +1,9 @@
use gateway::Shard;
use internal::prelude::*;
-use parking_lot::Mutex as ParkingLotMutex;
+use parking_lot::Mutex;
use std::collections::HashMap;
use std::sync::mpsc::{Receiver, Sender};
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
use super::super::super::EventHandler;
@@ -27,13 +27,13 @@ use framework::Framework;
/// blocking nature of the loop itself as well as a 5 second thread sleep
/// between shard starts.
pub struct ShardQueuer<H: EventHandler + Send + Sync + 'static> {
- pub data: Arc<ParkingLotMutex<ShareMap>>,
+ pub data: Arc<Mutex<ShareMap>>,
pub event_handler: Arc<H>,
#[cfg(feature = "framework")]
pub framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
pub last_start: Option<Instant>,
pub manager_tx: Sender<ShardManagerMessage>,
- pub runners: Arc<ParkingLotMutex<HashMap<ShardId, ShardRunnerInfo>>>,
+ pub runners: Arc<Mutex<HashMap<ShardId, ShardRunnerInfo>>>,
pub rx: Receiver<ShardQueuerMessage>,
pub threadpool: ThreadPool,
pub token: Arc<Mutex<String>>,
@@ -81,7 +81,7 @@ impl<H: EventHandler + Send + Sync + 'static> ShardQueuer<H> {
fn start(&mut self, shard_id: ShardId, shard_total: ShardId) -> Result<()> {
let shard_info = [shard_id.0, shard_total.0];
let shard = Shard::new(self.ws_url.clone(), self.token.clone(), shard_info)?;
- let locked = Arc::new(ParkingLotMutex::new(shard));
+ let locked = Arc::new(Mutex::new(shard));
let mut runner = feature_framework! {{
ShardRunner::new(
diff --git a/src/client/bridge/gateway/shard_runner.rs b/src/client/bridge/gateway/shard_runner.rs
index 1b1de0e..53d4b80 100644
--- a/src/client/bridge/gateway/shard_runner.rs
+++ b/src/client/bridge/gateway/shard_runner.rs
@@ -1,7 +1,7 @@
use internal::prelude::*;
use internal::ws_impl::ReceiverExt;
use model::event::{Event, GatewayEvent};
-use parking_lot::Mutex as ParkingLotMutex;
+use parking_lot::Mutex;
use std::sync::mpsc::{self, Receiver, Sender};
use std::sync::Arc;
use super::super::super::{EventHandler, dispatch};
@@ -12,11 +12,9 @@ use websocket::WebSocketError;
#[cfg(feature = "framework")]
use framework::Framework;
-#[cfg(feature = "framework")]
-use std::sync::Mutex;
pub struct ShardRunner<H: EventHandler + Send + Sync + 'static> {
- data: Arc<ParkingLotMutex<ShareMap>>,
+ data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>,
#[cfg(feature = "framework")]
framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
@@ -34,7 +32,7 @@ impl<H: EventHandler + Send + Sync + 'static> ShardRunner<H> {
shard: LockedShard,
manager_tx: Sender<ShardManagerMessage>,
framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
- data: Arc<ParkingLotMutex<ShareMap>>,
+ data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>,
threadpool: ThreadPool,
) -> Self {
@@ -58,7 +56,7 @@ impl<H: EventHandler + Send + Sync + 'static> ShardRunner<H> {
pub fn new(
shard: LockedShard,
manager_tx: Sender<ShardManagerMessage>,
- data: Arc<ParkingLotMutex<ShareMap>>,
+ data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>,
threadpool: ThreadPool,
) -> Self {
diff --git a/src/client/context.rs b/src/client/context.rs
index 2288f28..18500d6 100644
--- a/src/client/context.rs
+++ b/src/client/context.rs
@@ -83,7 +83,7 @@ impl Context {
feature_cache! {
{
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
map.insert("username".to_string(), Value::String(cache.user.name.clone()));
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs
index 709e34b..aec6283 100644
--- a/src/client/dispatch.rs
+++ b/src/client/dispatch.rs
@@ -15,8 +15,6 @@ use framework::Framework;
use model::GuildId;
#[cfg(feature = "cache")]
use std::{thread, time};
-#[cfg(feature = "framework")]
-use std::sync;
#[cfg(feature = "cache")]
use super::CACHE;
@@ -26,7 +24,7 @@ macro_rules! update {
{
#[cfg(feature="cache")]
{
- CACHE.write().unwrap().update(&mut $event)
+ CACHE.write().update(&mut $event)
}
}
};
@@ -44,7 +42,7 @@ fn context(conn: Arc<Mutex<Shard>>, data: Arc<Mutex<ShareMap>>) -> Context {
#[cfg(feature = "framework")]
pub fn dispatch<H: EventHandler + 'static>(event: Event,
conn: Arc<Mutex<Shard>>,
- framework: Arc<sync::Mutex<Option<Box<Framework + Send>>>>,
+ framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
data: Arc<Mutex<ShareMap>>,
event_handler: Arc<H>) {
match event {
@@ -56,7 +54,7 @@ pub fn dispatch<H: EventHandler + 'static>(event: Event,
event_handler,
);
- if let Some(ref mut framework) = *framework.lock().unwrap() {
+ if let Some(ref mut framework) = *framework.lock() {
framework.dispatch(context, event.message);
}
},
@@ -102,7 +100,7 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
#[cfg(feature = "cache")]
let wait_for_guilds = move || -> ::Result<()> {
- let unavailable_guilds = CACHE.read().unwrap().unavailable_guilds.len();
+ let unavailable_guilds = CACHE.read().unavailable_guilds.len();
while unavailable_guilds != 0 && (now!() < last_guild_create_time + 2000) {
thread::sleep(time::Duration::from_millis(500));
@@ -173,7 +171,7 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
let context = context(conn, data);
feature_cache! {{
- let before = CACHE.read().unwrap().channel(event.channel.id());
+ let before = CACHE.read().channel(event.channel.id());
event_handler.on_channel_update(context, before, event.channel);
} else {
event_handler.on_channel_update(context, event.channel);
@@ -192,7 +190,7 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
Event::GuildCreate(mut event) => {
#[cfg(feature = "cache")]
let _is_new = {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
!cache.unavailable_guilds.contains(&event.guild.id)
};
@@ -203,7 +201,7 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
{
last_guild_create_time = now!();
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
if cache.unavailable_guilds.is_empty() {
let context = context(conn.clone(), data.clone());
@@ -274,7 +272,6 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
// the member if it did not exist. So, there is be _no_ way
// that this could fail under any circumstance.
let after = CACHE.read()
- .unwrap()
.member(event.guild_id, event.user.id)
.unwrap()
.clone();
@@ -332,7 +329,6 @@ fn handle_event<H: EventHandler + 'static>(event: Event,
feature_cache! {{
let before = CACHE.read()
- .unwrap()
.guilds
.get(&event.guild.id)
.cloned();
diff --git a/src/client/event_handler.rs b/src/client/event_handler.rs
index 6e3c78e..0c618c2 100644
--- a/src/client/event_handler.rs
+++ b/src/client/event_handler.rs
@@ -1,3 +1,4 @@
+use parking_lot::RwLock;
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
@@ -5,8 +6,6 @@ use super::context::Context;
use model::event::*;
use model::*;
-use std::sync::RwLock;
-
pub trait EventHandler {
#[cfg(feature = "cache")]
fn on_cached(&self, _: Context, _: Vec<GuildId>) {}
diff --git a/src/client/mod.rs b/src/client/mod.rs
index f2fb297..c17e284 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -39,7 +39,7 @@ pub use CACHE;
use self::bridge::gateway::{ShardId, ShardManager, ShardRunnerInfo};
use self::dispatch::dispatch;
-use std::sync::{self, Arc};
+use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use parking_lot::Mutex;
use std::collections::HashMap;
@@ -192,7 +192,7 @@ pub struct Client<H: EventHandler + Send + Sync + 'static> {
/// [`Event::Ready`]: ../model/event/enum.Event.html#variant.Ready
/// [`on_ready`]: #method.on_ready
event_handler: Arc<H>,
- #[cfg(feature = "framework")] framework: Arc<sync::Mutex<Option<Box<Framework + Send>>>>,
+ #[cfg(feature = "framework")] framework: Arc<Mutex<Option<Box<Framework + Send>>>>,
/// A HashMap of all shards instantiated by the Client.
///
/// The key is the shard ID and the value is the shard itself.
@@ -250,7 +250,7 @@ pub struct Client<H: EventHandler + Send + Sync + 'static> {
/// Defaults to 5 threads, which should suffice small bots. Consider
/// increasing this number as your bot grows.
pub threadpool: ThreadPool,
- token: Arc<sync::Mutex<String>>,
+ token: Arc<Mutex<String>>,
}
impl<H: EventHandler + Send + Sync + 'static> Client<H> {
@@ -291,7 +291,7 @@ impl<H: EventHandler + Send + Sync + 'static> Client<H> {
};
http::set_token(&token);
- let locked = Arc::new(sync::Mutex::new(token));
+ let locked = Arc::new(Mutex::new(token));
let name = "serenity client".to_owned();
let threadpool = ThreadPool::with_name(name, 5);
@@ -300,7 +300,7 @@ impl<H: EventHandler + Send + Sync + 'static> Client<H> {
Client {
data: Arc::new(Mutex::new(ShareMap::custom())),
event_handler: Arc::new(handler),
- framework: Arc::new(sync::Mutex::new(None)),
+ framework: Arc::new(Mutex::new(None)),
shard_runners: Arc::new(Mutex::new(HashMap::new())),
threadpool,
token: locked,
@@ -417,7 +417,7 @@ impl<H: EventHandler + Send + Sync + 'static> Client<H> {
/// [framework docs]: ../framework/index.html
#[cfg(feature = "framework")]
pub fn with_framework<F: Framework + Send + 'static>(&mut self, f: F) {
- self.framework = Arc::new(sync::Mutex::new(Some(Box::new(f))));
+ self.framework = Arc::new(Mutex::new(Some(Box::new(f))));
}
/// Establish the connection and start listening for events.
@@ -755,12 +755,12 @@ impl<H: EventHandler + Send + Sync + 'static> Client<H> {
{
let user = http::get_current_user()?;
- if let Some(ref mut framework) = *self.framework.lock().unwrap() {
+ if let Some(ref mut framework) = *self.framework.lock() {
framework.update_current_user(user.id, user.bot);
}
}
- let gateway_url = Arc::new(sync::Mutex::new(url));
+ let gateway_url = Arc::new(Mutex::new(url));
let mut manager = ShardManager::new(
shard_data[0],
diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs
index 9bae941..dbf25a9 100644
--- a/src/framework/standard/help_commands.rs
+++ b/src/framework/standard/help_commands.rs
@@ -51,7 +51,7 @@ fn remove_aliases(cmds: &HashMap<String, CommandOrAlias>) -> HashMap<&String, &I
result
}
-/// Checks whether a user is member of required roles
+/// Checks whether a user is member of required roles
/// and given the required permissions.
fn has_all_requirements(cmd: &Command, guild: &Guild, member: &Member, msg: &Message) -> bool {
if cmd.allowed_roles.is_empty() {
@@ -102,7 +102,8 @@ pub fn with_embeds(_: &mut Context,
CommandOrAlias::Command(ref cmd) => {
if !cmd.allowed_roles.is_empty() {
if let Some(guild) = msg.guild() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
+
if let Some(member) = guild.members.get(&msg.author.id) {
if let Ok(permissions) = member.permissions() {
if !permissions.administrator() &&
@@ -209,7 +210,8 @@ pub fn with_embeds(_: &mut Context,
if cmd.help_available {
if let Some(guild) = msg.guild() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
+
if let Some(member) = guild.members.get(&msg.author.id) {
if let Ok(permissions) = member.permissions() {
if cmd.help_available &&
@@ -275,7 +277,8 @@ pub fn plain(_: &mut Context,
CommandOrAlias::Command(ref cmd) => {
if !cmd.allowed_roles.is_empty() {
if let Some(guild) = msg.guild() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
+
if let Some(member) = guild.members.get(&msg.author.id) {
if let Ok(permissions) = member.permissions() {
if !permissions.administrator() &&
@@ -362,7 +365,8 @@ pub fn plain(_: &mut Context,
for name in command_names {
let cmd = &commands[name];
if let Some(guild) = msg.guild() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
+
if let Some(member) = guild.members.get(&msg.author.id) {
if let Ok(permissions) = member.permissions() {
if cmd.help_available &&
diff --git a/src/framework/standard/mod.rs b/src/framework/standard/mod.rs
index a44c6e7..c3f0d70 100644
--- a/src/framework/standard/mod.rs
+++ b/src/framework/standard/mod.rs
@@ -400,7 +400,7 @@ impl StandardFramework {
#[cfg(feature = "cache")]
fn is_blocked_guild(&self, message: &Message) -> bool {
- if let Some(Channel::Guild(channel)) = CACHE.read().unwrap().channel(message.channel_id) {
+ if let Some(Channel::Guild(channel)) = CACHE.read().channel(message.channel_id) {
let guild_id = channel.with(|g| g.guild_id);
if self.configuration.blocked_guilds.contains(&guild_id) {
return true;
@@ -510,7 +510,8 @@ impl StandardFramework {
} else {
if !command.allowed_roles.is_empty() {
if let Some(guild) = message.guild() {
- let guild = guild.read().unwrap();
+ let guild = guild.read();
+
if let Some(member) = guild.members.get(&message.author.id) {
if let Ok(permissions) = member.permissions() {
if !permissions.administrator() {
diff --git a/src/gateway/shard.rs b/src/gateway/shard.rs
index 7e81813..379d183 100644
--- a/src/gateway/shard.rs
+++ b/src/gateway/shard.rs
@@ -1,9 +1,10 @@
use chrono::Utc;
+use parking_lot::Mutex;
use serde_json::Value;
use std::env::consts;
use std::io::Write;
use std::net::Shutdown;
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::time::{Duration as StdDuration, Instant};
use super::{ConnectionStage, GatewayError};
use websocket::client::Url;
@@ -108,25 +109,39 @@ impl Shard {
/// Instantiating a new Shard manually for a bot with no shards, and
/// then listening for events:
///
- /// ```rust,ignore
+ /// ```rust,no_run
+ /// extern crate parking_lot;
+ /// extern crate serenity;
+ /// #
+ /// # use std::error::Error;
+ /// #
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// #
+ /// use parking_lot::Mutex;
/// use serenity::gateway::Shard;
/// use serenity::http;
/// use std::env;
+ /// use std::sync::Arc;
///
- /// let token = env::var("DISCORD_BOT_TOKEN").expect("Token in environment");
+ /// let token = Arc::new(Mutex::new(env::var("DISCORD_BOT_TOKEN")?));
/// // retrieve the gateway response, which contains the URL to connect to
- /// let gateway = http::get_gateway().expect("Valid gateway response").url;
- /// let shard = Shard::new(&gateway, &token, None)
- /// .expect("Working shard");
+ /// let gateway = Arc::new(Mutex::new(http::get_gateway()?.url));
+ /// let shard = Shard::new(gateway, token, [0, 1])?;
///
/// // at this point, you can create a `loop`, and receive events and match
/// // their variants
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
pub fn new(ws_url: Arc<Mutex<String>>,
token: Arc<Mutex<String>>,
shard_info: [u64; 2])
-> Result<Shard> {
- let client = connect(&*ws_url.lock().unwrap())?;
+ let client = connect(&*ws_url.lock())?;
let current_presence = (None, OnlineStatus::Online, false);
let heartbeat_instants = (None, None);
@@ -188,14 +203,26 @@ impl Shard {
/// Retrieving the shard info for the second shard, out of two shards total:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let shard = Shard::new(mutex.clone(), mutex, [1, 2]).unwrap();
+ /// # let shard = Shard::new(mutex.clone(), mutex, [1, 2]).unwrap();
/// #
/// assert_eq!(shard.shard_info(), [1, 2]);
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
pub fn shard_info(&self) -> [u64; 2] { self.shard_info }
@@ -218,16 +245,28 @@ impl Shard {
/// Setting the current game to playing `"Heroes of the Storm"`:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
/// #
/// use serenity::model::Game;
///
/// shard.set_game(Some(Game::playing("Heroes of the Storm")));
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
pub fn set_game(&mut self, game: Option<Game>) {
self.current_presence.0 = game;
@@ -247,16 +286,28 @@ impl Shard {
/// Setting the current online status for the shard to [`DoNotDisturb`].
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
/// #
/// use serenity::model::OnlineStatus;
///
/// shard.set_status(OnlineStatus::DoNotDisturb);
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
///
/// [`DoNotDisturb`]: ../../model/enum.OnlineStatus.html#variant.DoNotDisturb
@@ -282,17 +333,29 @@ impl Shard {
/// and not being afk:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
/// #
/// use serenity::model::{Game, OnlineStatus};
///
/// shard.set_presence(Some(Game::playing("Heroes of the Storm")), OnlineStatus::Online,
/// false);
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
pub fn set_presence(&mut self, game: Option<Game>, mut status: OnlineStatus, afk: bool) {
if status == OnlineStatus::Offline {
@@ -638,36 +701,60 @@ impl Shard {
/// specifying a query parameter:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1])?;
/// #
/// use serenity::model::GuildId;
///
/// let guild_ids = vec![GuildId(81384788765712384)];
///
/// shard.chunk_guilds(&guild_ids, Some(2000), None);
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
///
/// Chunk a single guild by Id, limiting to 20 members, and specifying a
/// query parameter of `"do"`:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("".to_string()));
/// #
- /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1])?;
/// #
/// use serenity::model::GuildId;
///
/// let guild_ids = vec![GuildId(81384788765712384)];
///
/// shard.chunk_guilds(&guild_ids, Some(20), Some("do"));
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
///
/// [`Event::GuildMembersChunk`]:
@@ -702,24 +789,36 @@ impl Shard {
/// Retrieve the number of guilds a shard is responsible for:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use parking_lot::Mutex;
/// # use serenity::client::gateway::Shard;
- /// # use std::sync::{Arc, Mutex};
+ /// # use std::error::Error;
+ /// # use std::sync::Arc;
/// #
- /// # let mutex = Arc::new(Mutex::new("will anyone read this".to_string()));
+ /// # fn try_main() -> Result<(), Box<Error>> {
+ /// # let mutex = Arc::new(Mutex::new("will anyone read this".to_string()));
/// #
- /// # let shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
+ /// # let shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap();
/// #
/// let info = shard.shard_info();
/// let guilds = shard.guilds_handled();
///
/// println!("Shard {:?} is responsible for {} guilds", info, guilds);
+ /// # Ok(())
+ /// # }
+ /// #
+ /// # fn main() {
+ /// # try_main().unwrap();
+ /// # }
/// ```
///
/// [`Cache`]: ../ext/cache/struct.Cache.html
/// [`Guild`]: ../model/struct.Guild.html
#[cfg(feature = "cache")]
pub fn guilds_handled(&self) -> u16 {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
let (shard_id, shard_count) = (self.shard_info[0], self.shard_info[1]);
@@ -926,7 +1025,7 @@ impl Shard {
"d": {
"session_id": session_id,
"seq": self.seq,
- "token": &*self.token.lock().unwrap(),
+ "token": &*self.token.lock(),
},
}))
}
@@ -947,7 +1046,7 @@ impl Shard {
// This is used to accurately assess whether the state of the shard is
// accurate when a Hello is received.
self.stage = ConnectionStage::Connecting;
- self.client = connect(&self.ws_url.lock().unwrap())?;
+ self.client = connect(&self.ws_url.lock())?;
self.stage = ConnectionStage::Handshake;
Ok(())
@@ -960,7 +1059,7 @@ impl Shard {
"compression": true,
"large_threshold": constants::LARGE_THRESHOLD,
"shard": self.shard_info,
- "token": &*self.token.lock().unwrap(),
+ "token": &*self.token.lock(),
"v": constants::GATEWAY_VERSION,
"properties": {
"$browser": "serenity",
@@ -1015,7 +1114,7 @@ impl Shard {
#[cfg(feature = "cache")]
{
- let mut cache = CACHE.write().unwrap();
+ let mut cache = CACHE.write();
let current_user_id = cache.user.id;
cache.presences.get_mut(&current_user_id).map(|presence| {
diff --git a/src/http/mod.rs b/src/http/mod.rs
index 2348794..d6b32f1 100644
--- a/src/http/mod.rs
+++ b/src/http/mod.rs
@@ -38,6 +38,7 @@ use hyper::net::HttpsConnector;
use hyper::{header, Error as HyperError, Result as HyperResult, Url};
use hyper_native_tls::NativeTlsClient;
use multipart::client::Multipart;
+use parking_lot::Mutex;
use self::ratelimiting::Route;
use serde_json;
use std::collections::BTreeMap;
@@ -46,7 +47,7 @@ use std::fmt::Write as FmtWrite;
use std::fs::File;
use std::io::{ErrorKind as IoErrorKind, Read};
use std::path::{Path, PathBuf};
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use constants;
use internal::prelude::*;
use model::*;
@@ -98,7 +99,7 @@ lazy_static! {
/// # fn main() {
/// # try_main().unwrap();
/// # }
-pub fn set_token(token: &str) { TOKEN.lock().unwrap().clone_from(&token.to_string()); }
+pub fn set_token(token: &str) { TOKEN.lock().clone_from(&token.to_string()); }
/// Adds a [`User`] as a recipient to a [`Group`].
///
@@ -793,7 +794,7 @@ pub fn edit_profile(map: &JsonMap) -> Result<CurrentUser> {
let mut value = serde_json::from_reader::<HyperResponse, Value>(response)?;
if let Some(map) = value.as_object_mut() {
- if !TOKEN.lock().unwrap().starts_with("Bot ") {
+ if !TOKEN.lock().starts_with("Bot ") {
if let Some(Value::String(token)) = map.remove("token") {
set_token(&token);
}
@@ -1639,7 +1640,7 @@ pub fn send_files<'a, T, It: IntoIterator<Item=T>>(channel_id: u64, files: It, m
let mut request = Request::with_connector(Method::Post, url, &connector)?;
request
.headers_mut()
- .set(header::Authorization(TOKEN.lock().unwrap().clone()));
+ .set(header::Authorization(TOKEN.lock().clone()));
request
.headers_mut()
.set(header::UserAgent(constants::USER_AGENT.to_string()));
@@ -1798,7 +1799,7 @@ pub fn unpin_message(channel_id: u64, message_id: u64) -> Result<()> {
fn request<'a, F>(route: Route, f: F) -> Result<HyperResponse>
where F: Fn() -> RequestBuilder<'a> {
let response = ratelimiting::perform(route, || {
- f().header(header::Authorization(TOKEN.lock().unwrap().clone()))
+ f().header(header::Authorization(TOKEN.lock().clone()))
.header(header::ContentType::json())
})?;
diff --git a/src/http/ratelimiting.rs b/src/http/ratelimiting.rs
index 93ca4f6..09c2527 100644
--- a/src/http/ratelimiting.rs
+++ b/src/http/ratelimiting.rs
@@ -44,8 +44,9 @@ use chrono::Utc;
use hyper::client::{RequestBuilder, Response};
use hyper::header::Headers;
use hyper::status::StatusCode;
+use parking_lot::Mutex;
use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::time::Duration;
use std::{str, thread, i64};
use super::{HttpError, LightMethod};
@@ -80,10 +81,8 @@ lazy_static! {
/// ```rust,no_run
/// use serenity::http::ratelimiting::{ROUTES, Route};
///
- /// let routes = ROUTES.lock().unwrap();
- ///
- /// if let Some(route) = routes.get(&Route::ChannelsId(7)) {
- /// println!("Reset time at: {}", route.lock().unwrap().reset);
+ /// if let Some(route) = ROUTES.lock().get(&Route::ChannelsId(7)) {
+ /// println!("Reset time at: {}", route.lock().reset);
/// }
/// ```
///
@@ -352,7 +351,7 @@ pub(crate) fn perform<'a, F>(route: Route, f: F) -> Result<Response>
loop {
// This will block if another thread already has the global
// unlocked already (due to receiving an x-ratelimit-global).
- let _ = GLOBAL.lock().expect("global route lock poisoned");
+ let _ = GLOBAL.lock();
// Perform pre-checking here:
//
@@ -364,7 +363,6 @@ pub(crate) fn perform<'a, F>(route: Route, f: F) -> Result<Response>
// - then, perform the request
let bucket = ROUTES
.lock()
- .expect("routes poisoned")
.entry(route)
.or_insert_with(|| {
Arc::new(Mutex::new(RateLimit {
@@ -375,7 +373,7 @@ pub(crate) fn perform<'a, F>(route: Route, f: F) -> Result<Response>
})
.clone();
- let mut lock = bucket.lock().unwrap();
+ let mut lock = bucket.lock();
lock.pre_hook(&route);
let response = super::retry(&f)?;
@@ -397,7 +395,7 @@ pub(crate) fn perform<'a, F>(route: Route, f: F) -> Result<Response>
return Ok(response);
} else {
let redo = if response.headers.get_raw("x-ratelimit-global").is_some() {
- let _ = GLOBAL.lock().expect("global route lock poisoned");
+ let _ = GLOBAL.lock();
Ok(
if let Some(retry_after) = parse_header(&response.headers, "retry-after")? {
diff --git a/src/internal/rwlock_ext.rs b/src/internal/rwlock_ext.rs
index 8266cdf..6235370 100644
--- a/src/internal/rwlock_ext.rs
+++ b/src/internal/rwlock_ext.rs
@@ -1,3 +1,4 @@
+use parking_lot::RwLock as ParkingLotRwLock;
use std::sync::{Arc, RwLock};
pub trait RwLockExt<T> {
@@ -16,3 +17,15 @@ impl<T> RwLockExt<T> for Arc<RwLock<T>> {
f(&mut w)
}
}
+
+impl<T> RwLockExt<T> for Arc<ParkingLotRwLock<T>> {
+ fn with<Y, F: Fn(&T) -> Y>(&self, f: F) -> Y {
+ let r = self.read();
+ f(&r)
+ }
+
+ fn with_mut<Y, F: FnMut(&mut T) -> Y>(&self, mut f: F) -> Y {
+ let mut w = self.write();
+ f(&mut w)
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 612972a..a3710eb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -107,6 +107,7 @@ extern crate serde_json;
extern crate lazy_static;
extern crate chrono;
+extern crate parking_lot;
extern crate serde;
#[cfg(feature = "utils")]
@@ -125,8 +126,6 @@ extern crate multipart;
extern crate native_tls;
#[cfg(feature = "voice")]
extern crate opus;
-#[cfg(feature = "client")]
-extern crate parking_lot;
#[cfg(feature = "voice")]
extern crate sodiumoxide;
#[cfg(feature = "threadpool")]
@@ -172,7 +171,7 @@ pub use client::Client;
#[cfg(feature = "cache")]
use cache::Cache;
#[cfg(feature = "cache")]
-use std::sync::RwLock;
+use parking_lot::RwLock;
#[cfg(feature = "cache")]
lazy_static! {
@@ -197,16 +196,9 @@ lazy_static! {
/// ```rust,ignore
/// use serenity::CACHE;
///
- /// println!("{}", CACHE.read().unwrap().user.id);
+ /// println!("{}", CACHE.read().user.id);
/// ```
///
- /// By `unwrap()`ing, the thread managing an event dispatch will be blocked
- /// until the guard can be opened.
- ///
- /// If you do not want to block the current thread, you may instead use
- /// `RwLock::try_read`. Refer to `RwLock`'s documentation in the stdlib for
- /// more information.
- ///
/// [`CurrentUser`]: model/struct.CurrentUser.html
/// [`Cache`]: cache/struct.Cache.html
/// [cache module documentation]: cache/index.html
diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs
index f728191..4034fb9 100644
--- a/src/model/channel/channel_id.rs
+++ b/src/model/channel/channel_id.rs
@@ -224,14 +224,14 @@ impl ChannelId {
/// Search the cache for the channel with the Id.
#[cfg(feature = "cache")]
- pub fn find(&self) -> Option<Channel> { CACHE.read().unwrap().channel(*self) }
+ pub fn find(&self) -> Option<Channel> { CACHE.read().channel(*self) }
/// Search the cache for the channel. If it can't be found, the channel is
/// requested over REST.
pub fn get(&self) -> Result<Channel> {
#[cfg(feature = "cache")]
{
- if let Some(channel) = CACHE.read().unwrap().channel(*self) {
+ if let Some(channel) = CACHE.read().channel(*self) {
return Ok(channel);
}
}
@@ -311,13 +311,13 @@ impl ChannelId {
};
Some(match channel {
- Guild(channel) => channel.read().unwrap().name().to_string(),
- Group(channel) => match channel.read().unwrap().name() {
+ Guild(channel) => channel.read().name().to_string(),
+ Group(channel) => match channel.read().name() {
Cow::Borrowed(name) => name.to_string(),
Cow::Owned(name) => name,
},
- Category(category) => category.read().unwrap().name().to_string(),
- Private(channel) => channel.read().unwrap().name(),
+ Category(category) => category.read().name().to_string(),
+ Private(channel) => channel.read().name(),
})
}
diff --git a/src/model/channel/guild_channel.rs b/src/model/channel/guild_channel.rs
index e2e5f09..cc74b9d 100644
--- a/src/model/channel/guild_channel.rs
+++ b/src/model/channel/guild_channel.rs
@@ -157,12 +157,12 @@ impl GuildChannel {
/// kind: PermissionOverwriteType::Member(user_id),
/// };
///
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
/// let channel = cache
/// .guild_channel(channel_id)
/// .ok_or(ModelError::ItemMissing)?;
///
- /// channel.read().unwrap().create_permission(&overwrite)?;
+ /// channel.read().create_permission(&overwrite)?;
/// # Ok(())
/// # }
/// #
@@ -199,12 +199,12 @@ impl GuildChannel {
/// kind: PermissionOverwriteType::Member(user_id),
/// };
///
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
/// let channel = cache
/// .guild_channel(channel_id)
/// .ok_or(ModelError::ItemMissing)?;
///
- /// channel.read().unwrap().create_permission(&overwrite)?;
+ /// channel.read().create_permission(&overwrite)?;
/// # Ok(())
/// # }
/// #
@@ -365,7 +365,7 @@ impl GuildChannel {
/// **Note**: Right now this performs a clone of the guild. This will be
/// optimized in the future.
#[cfg(feature = "cache")]
- pub fn guild(&self) -> Option<Arc<RwLock<Guild>>> { CACHE.read().unwrap().guild(self.guild_id) }
+ pub fn guild(&self) -> Option<Arc<RwLock<Guild>>> { CACHE.read().guild(self.guild_id) }
/// Gets all of the channel's invites.
///
@@ -436,12 +436,12 @@ impl GuildChannel {
///
/// impl EventHandler for Handler {
/// fn on_message(&self, _: Context, msg: Message) {
- /// let channel = match CACHE.read().unwrap().guild_channel(msg.channel_id) {
+ /// let channel = match CACHE.read().guild_channel(msg.channel_id) {
/// Some(channel) => channel,
/// None => return,
/// };
///
- /// let permissions = channel.read().unwrap().permissions_for(&msg.author).unwrap();
+ /// let permissions = channel.read().permissions_for(&msg.author).unwrap();
///
/// println!("The user's permissions: {:?}", permissions);
/// }
@@ -464,14 +464,14 @@ impl GuildChannel {
///
/// impl EventHandler for Handler {
/// fn on_message(&self, _: Context, msg: Message) {
- /// let channel = match CACHE.read().unwrap().guild_channel(msg.channel_id) {
+ /// let channel = match CACHE.read().guild_channel(msg.channel_id) {
/// Some(channel) => channel,
/// None => return,
/// };
///
- /// let current_user_id = CACHE.read().unwrap().user.id;
+ /// let current_user_id = CACHE.read().user.id;
/// let permissions =
- /// channel.read().unwrap().permissions_for(current_user_id).unwrap();
+ /// channel.read().permissions_for(current_user_id).unwrap();
///
/// if !permissions.contains(Permissions::ATTACH_FILES |
/// Permissions::SEND_MESSAGES) {
@@ -512,7 +512,7 @@ impl GuildChannel {
pub fn permissions_for<U: Into<UserId>>(&self, user_id: U) -> Result<Permissions> {
self.guild()
.ok_or_else(|| Error::Model(ModelError::GuildNotFound))
- .map(|g| g.read().unwrap().permissions_for(self.id, user_id))
+ .map(|g| g.read().permissions_for(self.id, user_id))
}
/// Pins a [`Message`] to the channel.
diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs
index 55f61ba..f6efd74 100644
--- a/src/model/channel/message.rs
+++ b/src/model/channel/message.rs
@@ -97,12 +97,12 @@ impl Message {
///
/// command!(channel_name(_ctx, msg) {
/// let _ = match msg.channel() {
- /// Some(Channel::Category(c)) => msg.reply(&c.read().unwrap().name),
- /// Some(Channel::Group(c)) => msg.reply(&c.read().unwrap().name()),
- /// Some(Channel::Guild(c)) => msg.reply(&c.read().unwrap().name),
+ /// Some(Channel::Category(c)) => msg.reply(&c.read().name),
+ /// Some(Channel::Group(c)) => msg.reply(&c.read().name()),
+ /// Some(Channel::Guild(c)) => msg.reply(&c.read().name),
/// Some(Channel::Private(c)) => {
- /// let channel = c.read().unwrap();
- /// let user = channel.recipient.read().unwrap();
+ /// let channel = c.read();
+ /// let user = channel.recipient.read();
///
/// msg.reply(&format!("DM with {}", user.name.clone()))
/// },
@@ -113,12 +113,12 @@ impl Message {
/// ```
#[cfg(feature = "cache")]
#[inline]
- pub fn channel(&self) -> Option<Channel> { CACHE.read().unwrap().channel(self.channel_id) }
+ pub fn channel(&self) -> Option<Channel> { CACHE.read().channel(self.channel_id) }
/// A util function for determining whether this message was sent by someone else, or the
/// bot.
#[cfg(all(feature = "cache", feature = "utils"))]
- pub fn is_own(&self) -> bool { self.author.id == CACHE.read().unwrap().user.id }
+ pub fn is_own(&self) -> bool { self.author.id == CACHE.read().user.id }
/// Deletes the message.
///
@@ -138,7 +138,7 @@ impl Message {
#[cfg(feature = "cache")]
{
let req = Permissions::MANAGE_MESSAGES;
- let is_author = self.author.id == CACHE.read().unwrap().user.id;
+ let is_author = self.author.id == CACHE.read().user.id;
let has_perms = utils::user_has_perms(self.channel_id, req)?;
if !is_author && !has_perms {
@@ -211,7 +211,7 @@ impl Message {
where F: FnOnce(CreateMessage) -> CreateMessage {
#[cfg(feature = "cache")]
{
- if self.author.id != CACHE.read().unwrap().user.id {
+ if self.author.id != CACHE.read().user.id {
return Err(Error::Model(ModelError::InvalidUser));
}
}
@@ -335,7 +335,7 @@ impl Message {
#[cfg(feature = "cache")]
pub fn guild(&self) -> Option<Arc<RwLock<Guild>>> {
self.guild_id()
- .and_then(|guild_id| CACHE.read().unwrap().guild(guild_id))
+ .and_then(|guild_id| CACHE.read().guild(guild_id))
}
/// Retrieves the Id of the guild that the message was sent in, if sent in
@@ -345,8 +345,8 @@ impl Message {
/// cache.
#[cfg(feature = "cache")]
pub fn guild_id(&self) -> Option<GuildId> {
- match CACHE.read().unwrap().channel(self.channel_id) {
- Some(Channel::Guild(ch)) => Some(ch.read().unwrap().guild_id),
+ match CACHE.read().channel(self.channel_id) {
+ Some(Channel::Guild(ch)) => Some(ch.read().guild_id),
_ => None,
}
}
@@ -354,7 +354,7 @@ impl Message {
/// True if message was sent using direct messages.
#[cfg(feature = "cache")]
pub fn is_private(&self) -> bool {
- match CACHE.read().unwrap().channel(self.channel_id) {
+ match CACHE.read().channel(self.channel_id) {
Some(Channel::Group(_)) | Some(Channel::Private(_)) => true,
_ => false,
}
diff --git a/src/model/channel/mod.rs b/src/model/channel/mod.rs
index 4ba0322..f7ecc0f 100644
--- a/src/model/channel/mod.rs
+++ b/src/model/channel/mod.rs
@@ -83,16 +83,16 @@ impl Channel {
pub fn delete(&self) -> Result<()> {
match *self {
Channel::Group(ref group) => {
- let _ = group.read().unwrap().leave()?;
+ let _ = group.read().leave()?;
},
Channel::Guild(ref public_channel) => {
- let _ = public_channel.read().unwrap().delete()?;
+ let _ = public_channel.read().delete()?;
},
Channel::Private(ref private_channel) => {
- let _ = private_channel.read().unwrap().delete()?;
+ let _ = private_channel.read().delete()?;
},
Channel::Category(ref category) => {
- category.read().unwrap().delete()?;
+ category.read().delete()?;
},
}
@@ -375,15 +375,15 @@ impl Display for Channel {
/// [`PrivateChannel`]: struct.PrivateChannel.html
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match *self {
- Channel::Group(ref group) => Display::fmt(&group.read().unwrap().name(), f),
- Channel::Guild(ref ch) => Display::fmt(&ch.read().unwrap().id.mention(), f),
+ Channel::Group(ref group) => Display::fmt(&group.read().name(), f),
+ Channel::Guild(ref ch) => Display::fmt(&ch.read().id.mention(), f),
Channel::Private(ref ch) => {
- let channel = ch.read().unwrap();
- let recipient = channel.recipient.read().unwrap();
+ let channel = ch.read();
+ let recipient = channel.recipient.read();
Display::fmt(&recipient.name, f)
},
- Channel::Category(ref category) => Display::fmt(&category.read().unwrap().name, f),
+ Channel::Category(ref category) => Display::fmt(&category.read().name, f),
}
}
}
diff --git a/src/model/channel/private_channel.rs b/src/model/channel/private_channel.rs
index d6ba781..01b387a 100644
--- a/src/model/channel/private_channel.rs
+++ b/src/model/channel/private_channel.rs
@@ -279,6 +279,6 @@ impl PrivateChannel {
impl Display for PrivateChannel {
/// Formats the private channel, displaying the recipient's username.
fn fmt(&self, f: &mut Formatter) -> FmtResult {
- f.write_str(&self.recipient.read().unwrap().name)
+ f.write_str(&self.recipient.read().name)
}
}
diff --git a/src/model/channel/reaction.rs b/src/model/channel/reaction.rs
index 8edc2e9..1a40ecb 100644
--- a/src/model/channel/reaction.rs
+++ b/src/model/channel/reaction.rs
@@ -48,7 +48,7 @@ impl Reaction {
pub fn delete(&self) -> Result<()> {
let user_id = feature_cache! {
{
- let user = if self.user_id == CACHE.read().unwrap().user.id {
+ let user = if self.user_id == CACHE.read().user.id {
None
} else {
Some(self.user_id.0)
diff --git a/src/model/event.rs b/src/model/event.rs
index fe65269..8d949c7 100644
--- a/src/model/event.rs
+++ b/src/model/event.rs
@@ -61,7 +61,7 @@ impl CacheUpdate for ChannelCreateEvent {
let channel_id = group.with_mut(|writer| {
for (recipient_id, recipient) in &mut writer.recipients {
- cache.update_user_entry(&recipient.read().unwrap());
+ cache.update_user_entry(&recipient.read());
*recipient = cache.users[recipient_id].clone();
}
@@ -110,7 +110,7 @@ impl CacheUpdate for ChannelCreateEvent {
},
Channel::Category(ref category) => cache
.categories
- .insert(category.read().unwrap().id, category.clone())
+ .insert(category.read().id, category.clone())
.map(Channel::Category),
}
}
@@ -214,7 +214,7 @@ impl CacheUpdate for ChannelRecipientAddEvent {
let user = cache.users[&self.user.id].clone();
cache.groups.get_mut(&self.channel_id).map(|group| {
- group.write().unwrap().recipients.insert(self.user.id, user);
+ group.write().recipients.insert(self.user.id, user);
});
None
@@ -263,16 +263,16 @@ impl CacheUpdate for ChannelUpdateEvent {
e.insert(group.clone());
},
Entry::Occupied(mut e) => {
- let mut dest = e.get_mut().write().unwrap();
+ let mut dest = e.get_mut().write();
if no_recipients {
let recipients = mem::replace(&mut dest.recipients, HashMap::new());
- dest.clone_from(&group.read().unwrap());
+ dest.clone_from(&group.read());
dest.recipients = recipients;
} else {
- dest.clone_from(&group.read().unwrap());
+ dest.clone_from(&group.read());
}
},
}
@@ -289,13 +289,13 @@ impl CacheUpdate for ChannelUpdateEvent {
Channel::Private(ref channel) => {
cache
.private_channels
- .get_mut(&channel.read().unwrap().id)
+ .get_mut(&channel.read().id)
.map(|private| private.clone_from(channel));
},
Channel::Category(ref category) => {
cache
.categories
- .get_mut(&category.read().unwrap().id)
+ .get_mut(&category.read().id)
.map(|c| c.clone_from(category));
},
}
@@ -340,7 +340,7 @@ impl CacheUpdate for GuildCreateEvent {
let mut guild = self.guild.clone();
for (user_id, member) in &mut guild.members {
- cache.update_user_entry(&member.user.read().unwrap());
+ cache.update_user_entry(&member.user.read());
let user = cache.users[user_id].clone();
member.user = user.clone();
@@ -375,7 +375,7 @@ impl CacheUpdate for GuildDeleteEvent {
fn update(&mut self, cache: &mut Cache) -> Option<Self::Output> {
// Remove channel entries for the guild if the guild is found.
cache.guilds.remove(&self.guild.id).map(|guild| {
- for channel_id in guild.write().unwrap().channels.keys() {
+ for channel_id in guild.write().channels.keys() {
cache.channels.remove(channel_id);
}
@@ -428,7 +428,7 @@ impl CacheUpdate for GuildMemberAddEvent {
fn update(&mut self, cache: &mut Cache) -> Option<()> {
let user_id = self.member.user.with(|u| u.id);
- cache.update_user_entry(&self.member.user.read().unwrap());
+ cache.update_user_entry(&self.member.user.read());
// Always safe due to being inserted above.
self.member.user = cache.users[&user_id].clone();
@@ -498,7 +498,7 @@ impl CacheUpdate for GuildMemberUpdateEvent {
cache.update_user_entry(&self.user);
if let Some(guild) = cache.guilds.get_mut(&self.guild_id) {
- let mut guild = guild.write().unwrap();
+ let mut guild = guild.write();
let mut found = false;
@@ -507,7 +507,7 @@ impl CacheUpdate for GuildMemberUpdateEvent {
member.nick.clone_from(&self.nick);
member.roles.clone_from(&self.roles);
- member.user.write().unwrap().clone_from(&self.user);
+ member.user.write().clone_from(&self.user);
found = true;
@@ -550,7 +550,7 @@ impl CacheUpdate for GuildMembersChunkEvent {
fn update(&mut self, cache: &mut Cache) -> Option<()> {
for member in self.members.values() {
- cache.update_user_entry(&member.user.read().unwrap());
+ cache.update_user_entry(&member.user.read());
}
cache.guilds.get_mut(&self.guild_id).map(|guild| {
@@ -607,7 +607,6 @@ impl CacheUpdate for GuildRoleCreateEvent {
cache.guilds.get_mut(&self.guild_id).map(|guild| {
guild
.write()
- .unwrap()
.roles
.insert(self.role.id, self.role.clone())
});
@@ -683,7 +682,7 @@ impl CacheUpdate for GuildUpdateEvent {
fn update(&mut self, cache: &mut Cache) -> Option<()> {
cache.guilds.get_mut(&self.guild.id).map(|guild| {
- let mut guild = guild.write().unwrap();
+ let mut guild = guild.write();
guild.afk_timeout = self.guild.afk_timeout;
guild.afk_channel_id.clone_from(&self.guild.afk_channel_id);
@@ -766,13 +765,13 @@ impl CacheUpdate for PresenceUpdateEvent {
let user_id = self.presence.user_id;
if let Some(user) = self.presence.user.as_mut() {
- cache.update_user_entry(&user.read().unwrap());
+ cache.update_user_entry(&user.read());
*user = cache.users[&user_id].clone();
}
if let Some(guild_id) = self.guild_id {
if let Some(guild) = cache.guilds.get_mut(&guild_id) {
- let mut guild = guild.write().unwrap();
+ let mut guild = guild.write();
// If the member went offline, remove them from the presence list.
if self.presence.status == OnlineStatus::Offline {
@@ -918,7 +917,7 @@ impl CacheUpdate for ReadyEvent {
for (user_id, presence) in &mut ready.presences {
if let Some(ref user) = presence.user {
- cache.update_user_entry(&user.read().unwrap());
+ cache.update_user_entry(&user.read());
}
presence.user = cache.users.get(user_id).cloned();
@@ -1002,7 +1001,7 @@ impl CacheUpdate for VoiceStateUpdateEvent {
fn update(&mut self, cache: &mut Cache) -> Option<()> {
if let Some(guild_id) = self.guild_id {
if let Some(guild) = cache.guilds.get_mut(&guild_id) {
- let mut guild = guild.write().unwrap();
+ let mut guild = guild.write();
if self.voice_state.channel_id.is_some() {
// Update or add to the voice state list
diff --git a/src/model/gateway.rs b/src/model/gateway.rs
index 4edc20e..ca846e8 100644
--- a/src/model/gateway.rs
+++ b/src/model/gateway.rs
@@ -1,6 +1,7 @@
+use parking_lot::RwLock;
use serde::de::Error as DeError;
use serde_json;
-use std::sync::{Arc, RwLock};
+use std::sync::Arc;
use super::utils::*;
use super::*;
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/guild_id.rs b/src/model/guild/guild_id.rs
index 4b9a713..efda6a8 100644
--- a/src/model/guild/guild_id.rs
+++ b/src/model/guild/guild_id.rs
@@ -305,7 +305,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.
///
@@ -408,7 +408,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 694de20..bca3ecb 100644
--- a/src/model/guild/member.rs
+++ b/src/model/guild/member.rs
@@ -88,7 +88,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);
@@ -111,7 +111,7 @@ impl Member {
let map = EditMember::default().roles(&self.roles).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 +149,7 @@ impl Member {
http::ban_user(
self.guild_id.0,
- self.user.read().unwrap().id.0,
+ self.user.read().id.0,
dmd,
&*reason,
)
@@ -158,9 +158,9 @@ 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 cache = CACHE.read();
let guild = match cache.guilds.get(&self.guild_id) {
- Some(guild) => guild.read().unwrap(),
+ Some(guild) => guild.read(),
None => return None,
};
@@ -187,10 +187,10 @@ impl Member {
None => return None,
};
- let reader = guild.read().unwrap();
+ let reader = guild.read();
for (cid, channel) in &reader.channels {
- if reader.permissions_for(*cid, self.user.read().unwrap().id).read_messages() {
+ if reader.permissions_for(*cid, self.user.read().id).read_messages() {
return Some(channel.clone());
}
}
@@ -206,7 +206,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.
@@ -215,7 +215,7 @@ impl Member {
format!(
"{}#{}",
self.display_name(),
- self.user.read().unwrap().discriminator
+ self.user.read().discriminator
)
}
@@ -231,7 +231,7 @@ impl Member {
pub fn edit<F: FnOnce(EditMember) -> EditMember>(&self, f: F) -> Result<()> {
let 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.
@@ -274,17 +274,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.
@@ -314,18 +313,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(self.user.read().unwrap().id) {
+ 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().unwrap();
+ let default_channel_reader = default_channel.read();
Ok(
guild
- .permissions_for(default_channel_reader.id, self.user.read().unwrap().id),
+ .permissions_for(default_channel_reader.id, self.user.read().id),
)
}
@@ -344,7 +343,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);
@@ -366,7 +365,7 @@ impl Member {
let map = EditMember::default().roles(&self.roles).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);
@@ -385,19 +384,17 @@ impl Member {
pub fn roles(&self) -> Option<Vec<Role>> {
CACHE
.read()
- .unwrap()
.guilds
.values()
.find(|guild| {
- guild.read().unwrap().members.values().any(|m| {
- m.user.read().unwrap().id == self.user.read().unwrap().id &&
+ guild.read().members.values().any(|m| {
+ m.user.read().id == self.user.read().id &&
m.joined_at == self.joined_at
})
})
.map(|guild| {
guild
.read()
- .unwrap()
.roles
.values()
.filter(|role| self.roles.contains(&role.id))
@@ -420,7 +417,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)
}
}
@@ -436,6 +433,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 73dfa73..ea6cb17 100644
--- a/src/model/guild/mod.rs
+++ b/src/model/guild/mod.rs
@@ -155,17 +155,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(member.user.read().unwrap().id) {
+ 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.read().unwrap().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())
@@ -406,7 +406,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)));
@@ -723,9 +723,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,
};
@@ -744,7 +744,7 @@ impl Guild {
/// - "zey", "zeyla", "zey mei"
/// If 'case_sensitive' is false, the following are not found:
/// - "Zey", "ZEYla", "zeY mei"
- ///
+ ///
/// [`Member`]: struct.Member.html
pub fn members_starting_with(&self, prefix: &str, case_sensitive: bool) -> Vec<&Member> {
self.members
@@ -752,11 +752,11 @@ 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()
.map_or(false, |nick|
@@ -773,7 +773,7 @@ impl Guild {
/// - "zeyla", "meiyla", "yladenisyla"
/// If 'case_sensitive' is false, the following are not found:
/// - "zeYLa", "meiyLa", "LYAdenislyA"
- ///
+ ///
/// [`Member`]: struct.Member.html
pub fn members_containing(&self, substring: &str, case_sensitive: bool) -> Vec<&Member> {
self.members
@@ -781,11 +781,11 @@ 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()
.map_or(false, |nick|
@@ -849,7 +849,7 @@ impl Guild {
} else {
warn!(
"(╯°□°)╯︵ ┻━┻ {} on {} has non-existent role {:?}",
- member.user.read().unwrap().id,
+ member.user.read().id,
self.id,
role
);
@@ -862,7 +862,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 {
@@ -1102,7 +1102,7 @@ impl Guild {
/// impl EventHandler for Handler {
/// fn on_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);
/// }
/// }
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;
diff --git a/src/model/mod.rs b/src/model/mod.rs
index 0817094..64987e1 100644
--- a/src/model/mod.rs
+++ b/src/model/mod.rs
@@ -32,11 +32,12 @@ pub use self::voice::*;
pub use self::webhook::*;
use chrono::NaiveDateTime;
+use parking_lot::RwLock;
use self::utils::*;
use serde::de::Visitor;
use std::collections::HashMap;
use std::fmt::{Display, Formatter, Result as FmtResult};
-use std::sync::{Arc, RwLock};
+use std::sync::Arc;
use internal::prelude::*;
#[cfg(feature = "utils")]
@@ -67,7 +68,7 @@ macro_rules! id_u64 {
self
}
}
-
+
impl From<u64> for $name {
fn from(id_as_u64: u64) -> $name {
$name(id_as_u64)
diff --git a/src/model/user.rs b/src/model/user.rs
index 39efa10..bf5ee36 100644
--- a/src/model/user.rs
+++ b/src/model/user.rs
@@ -7,12 +7,14 @@ use model::misc::Mentionable;
#[cfg(feature = "model")]
use chrono::NaiveDateTime;
+#[cfg(all(feature = "cache", feature = "model"))]
+use parking_lot::RwLock;
#[cfg(feature = "model")]
use std::fmt::Write;
#[cfg(feature = "model")]
use std::mem;
#[cfg(all(feature = "cache", feature = "model"))]
-use std::sync::{Arc, RwLock};
+use std::sync::Arc;
#[cfg(feature = "model")]
use builder::{CreateMessage, EditProfile};
#[cfg(all(feature = "cache", feature = "model"))]
@@ -46,7 +48,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let cache = CACHE.read().unwrap();
+ /// # let cache = CACHE.read();
/// #
/// // assuming the cache has been unlocked
/// let user = &cache.user;
@@ -80,7 +82,7 @@ impl CurrentUser {
///
/// let avatar = serenity::utils::read_image("./avatar.png").unwrap();
///
- /// CACHE.write().unwrap().user.edit(|p| p.avatar(Some(&avatar)));
+ /// CACHE.write().user.edit(|p| p.avatar(Some(&avatar)));
/// ```
pub fn edit<F>(&mut self, f: F) -> Result<()>
where F: FnOnce(EditProfile) -> EditProfile {
@@ -123,7 +125,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let cache = CACHE.read().unwrap();
+ /// # let cache = CACHE.read();
/// #
/// // assuming the cache has been unlocked
/// let user = &cache.user;
@@ -151,7 +153,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let mut cache = CACHE.write().unwrap();
+ /// # let mut cache = CACHE.write();
///
/// use serenity::model::permissions::Permissions;
///
@@ -174,7 +176,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let mut cache = CACHE.write().unwrap();
+ /// # let mut cache = CACHE.write();
///
/// use serenity::model::Permissions;
///
@@ -230,7 +232,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let cache = CACHE.read().unwrap();
+ /// # let cache = CACHE.read();
/// #
/// // assuming the cache has been unlocked
/// let user = &cache.user;
@@ -254,7 +256,7 @@ impl CurrentUser {
/// ```rust,no_run
/// # use serenity::client::CACHE;
/// #
- /// # let cache = CACHE.read().unwrap();
+ /// # let cache = CACHE.read();
/// #
/// // assuming the cache has been unlocked
/// println!("The current user's distinct identifier is {}", cache.user.tag());
@@ -410,25 +412,21 @@ impl User {
/// impl EventHandler for Handler {
/// fn on_message(&self, _: Context, msg: Message) {
/// if msg.content == "~help" {
- /// let url = match CACHE.read() {
- /// Ok(v) => {
- /// match v.user.invite_url(Permissions::empty()) {
- /// Ok(v) => v,
- /// Err(why) => {
- /// println!("Error creating invite url: {:?}", why);
- ///
- /// return;
- /// },
- /// }
- /// },
+ /// let cache = CACHE.read();
+ ///
+ /// let url = match cache.user.invite_url(Permissions::empty()) {
+ /// Ok(v) => v,
/// Err(why) => {
- /// println!("Error reading from CACHE: {:?}", why);
+ /// println!("Error creating invite url: {:?}", why);
///
/// return;
- /// }
+ /// },
/// };
- /// let help = format!("Helpful info here. Invite me with this link: <{}>",
- /// url);
+ ///
+ /// let help = format!(
+ /// "Helpful info here. Invite me with this link: <{}>",
+ /// url,
+ /// );
///
/// match msg.author.direct_message(|m| m.content(&help)) {
/// Ok(_) => {
@@ -480,12 +478,12 @@ impl User {
let private_channel_id = feature_cache! {
{
let finding = {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
let finding = cache.private_channels
.values()
- .map(|ch| ch.read().unwrap())
- .find(|ch| ch.recipient.read().unwrap().id == self.id)
+ .map(|ch| ch.read())
+ .find(|ch| ch.recipient.read().id == self.id)
.map(|ch| ch.id);
finding
@@ -580,10 +578,9 @@ impl User {
GuildContainer::Id(_guild_id) => {
feature_cache! {{
CACHE.read()
- .unwrap()
.guilds
.get(&_guild_id)
- .map(|g| g.read().unwrap().roles.contains_key(&role_id))
+ .map(|g| g.read().roles.contains_key(&role_id))
.unwrap_or(false)
} else {
true
@@ -631,11 +628,11 @@ impl User {
/// loop {
/// thread::sleep(duration);
///
- /// let cache = CACHE.read().unwrap();
+ /// let cache = CACHE.read();
///
/// for id in &special_users {
/// if let Some(user) = cache.user(*id) {
- /// if let Err(why) = user.write().unwrap().refresh() {
+ /// if let Err(why) = user.write().refresh() {
/// println!("Error refreshing {}: {:?}", id, why);
/// }
/// }
@@ -721,7 +718,7 @@ impl UserId {
/// Search the cache for the user with the Id.
#[cfg(feature = "cache")]
- pub fn find(&self) -> Option<Arc<RwLock<User>>> { CACHE.read().unwrap().user(*self) }
+ pub fn find(&self) -> Option<Arc<RwLock<User>>> { CACHE.read().user(*self) }
/// Gets a user by its Id over the REST API.
///
@@ -730,8 +727,8 @@ impl UserId {
pub fn get(&self) -> Result<User> {
#[cfg(feature = "cache")]
{
- if let Some(user) = CACHE.read().unwrap().user(*self) {
- return Ok(user.read().unwrap().clone());
+ if let Some(user) = CACHE.read().user(*self) {
+ return Ok(user.read().clone());
}
}
@@ -751,12 +748,12 @@ impl<'a> From<&'a CurrentUser> for UserId {
impl From<Member> for UserId {
/// Gets the Id of a `Member`.
- fn from(member: Member) -> UserId { member.user.read().unwrap().id }
+ fn from(member: Member) -> UserId { member.user.read().id }
}
impl<'a> From<&'a Member> for UserId {
/// Gets the Id of a `Member`.
- fn from(member: &Member) -> UserId { member.user.read().unwrap().id }
+ fn from(member: &Member) -> UserId { member.user.read().id }
}
impl From<User> for UserId {
diff --git a/src/model/utils.rs b/src/model/utils.rs
index 719a472..62ecc4e 100644
--- a/src/model/utils.rs
+++ b/src/model/utils.rs
@@ -1,6 +1,7 @@
+use parking_lot::RwLock;
use serde::de::Error as DeError;
use std::collections::HashMap;
-use std::sync::{Arc, RwLock};
+use std::sync::Arc;
use super::*;
#[cfg(feature = "cache")]
@@ -44,7 +45,7 @@ pub fn deserialize_members<'de, D: Deserializer<'de>>(
let mut members = HashMap::new();
for member in vec {
- let user_id = member.user.read().unwrap().id;
+ let user_id = member.user.read().id;
members.insert(user_id, member);
}
@@ -73,8 +74,8 @@ pub fn deserialize_private_channels<'de, D: Deserializer<'de>>(
for private_channel in vec {
let id = match private_channel {
- Channel::Group(ref group) => group.read().unwrap().channel_id,
- Channel::Private(ref channel) => channel.read().unwrap().id,
+ Channel::Group(ref group) => group.read().channel_id,
+ Channel::Private(ref channel) => channel.read().id,
Channel::Guild(_) => unreachable!("Guild private channel decode"),
Channel::Category(_) => unreachable!("Channel category private channel decode"),
};
@@ -147,7 +148,7 @@ pub fn deserialize_voice_states<'de, D: Deserializer<'de>>(
#[cfg(all(feature = "cache", feature = "model"))]
pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Result<bool> {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
let current_user = &cache.user;
let channel = match cache.channel(channel_id) {
@@ -156,7 +157,7 @@ pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Re
};
let guild_id = match channel {
- Channel::Guild(channel) => channel.read().unwrap().guild_id,
+ Channel::Guild(channel) => channel.read().guild_id,
Channel::Group(_) | Channel::Private(_) | Channel::Category(_) => {
// Both users in DMs, and all users in groups and maybe all channels in categories will
// have the same
@@ -177,10 +178,7 @@ pub fn user_has_perms(channel_id: ChannelId, mut permissions: Permissions) -> Re
None => return Err(Error::Model(ModelError::ItemMissing)),
};
- let perms = guild
- .read()
- .unwrap()
- .permissions_for(channel_id, current_user.id);
+ let perms = guild.read().permissions_for(channel_id, current_user.id);
permissions.remove(perms);
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 4b36b73..c6d27c3 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -455,7 +455,7 @@ pub fn shard_id(guild_id: u64, shard_count: u64) -> u64 { (guild_id >> 22) % sha
#[cfg(feature = "cache")]
pub fn with_cache<T, F>(f: F) -> T
where F: Fn(&Cache) -> T {
- let cache = CACHE.read().unwrap();
+ let cache = CACHE.read();
f(&cache)
}
@@ -476,6 +476,6 @@ pub fn with_cache<T, F>(f: F) -> T
#[cfg(feature = "cache")]
pub fn with_cache_mut<T, F>(mut f: F) -> T
where F: FnMut(&mut Cache) -> T {
- let mut cache = CACHE.write().unwrap();
+ let mut cache = CACHE.write();
f(&mut cache)
}
diff --git a/src/voice/connection.rs b/src/voice/connection.rs
index 3b31488..47b448c 100644
--- a/src/voice/connection.rs
+++ b/src/voice/connection.rs
@@ -1,4 +1,5 @@
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
+use parking_lot::Mutex;
use opus::{
packet as opus_packet,
Application as CodingMode,
@@ -11,7 +12,7 @@ use std::collections::HashMap;
use std::io::Write;
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
use std::sync::mpsc::{self, Receiver as MpscReceiver, Sender as MpscSender};
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use std::thread::{self, Builder as ThreadBuilder, JoinHandle};
use std::time::Duration;
use super::audio::{AudioReceiver, AudioSource, AudioType, HEADER_LEN, SAMPLE_RATE};
@@ -223,10 +224,7 @@ impl Connection {
// Send the voice websocket keepalive if it's time
if self.keepalive_timer.check() {
- self.client
- .lock()
- .unwrap()
- .send_json(&payload::build_keepalive())?;
+ self.client.lock().send_json(&payload::build_keepalive())?;
}
// Send UDP keepalive if it's time
@@ -357,10 +355,7 @@ impl Connection {
self.speaking = speaking;
- self.client
- .lock()
- .unwrap()
- .send_json(&payload::build_speaking(speaking))
+ self.client.lock().send_json(&payload::build_speaking(speaking))
}
}
@@ -452,7 +447,7 @@ fn start_threads(client: Arc<Mutex<Client>>, udp: &UdpSocket) -> Result<ThreadIt
let ws_thread = ThreadBuilder::new()
.name(format!("{} WS", thread_name))
.spawn(move || loop {
- while let Ok(Some(msg)) = client.lock().unwrap().recv_json(VoiceEvent::decode) {
+ while let Ok(Some(msg)) = client.lock().recv_json(VoiceEvent::decode) {
if tx_clone.send(ReceiverStatus::Websocket(msg)).is_ok() {
return;
}