Driver, Tracks: Cleanup of leaky types (#20)
Main goal: a lot of nested future/result folding. This mainly modifies error handling for Tracks and TrackHandles to be more consistent, and hides the underlying channel result passing in get_info. Errors returned should be far clearer, and are domain specific rather than falling back to a very opaque use of the underlying channel error. It should be clearer to users why their handle commands failed, or why they can't make a ytdl track loop or similar. Also fixed/cleaned up Songbird::join(_gateway) to return in a single await, sparing the user from the underlying channel details and repeated Errs. I was trying for some time to extend the same graces to `Call`, but could not figure out a sane way to get a 'static version of the first future in the chain (i.e., the gateway send) so that the whole thing could happen after dropping the lock around the Call. I really wanted to fix this to happen as a single folded await too, but I think this might need some crazy hack or redesign.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#[cfg(feature = "driver")]
|
||||
use crate::{driver::Config, error::ConnectionResult};
|
||||
use crate::driver::Config;
|
||||
use crate::{
|
||||
error::{JoinError, JoinResult},
|
||||
id::{ChannelId, GuildId, UserId},
|
||||
@@ -9,7 +9,6 @@ use crate::{
|
||||
};
|
||||
#[cfg(feature = "serenity")]
|
||||
use async_trait::async_trait;
|
||||
use flume::Receiver;
|
||||
#[cfg(feature = "serenity")]
|
||||
use futures::channel::mpsc::UnboundedSender as Sender;
|
||||
use parking_lot::RwLock as PRwLock;
|
||||
@@ -114,7 +113,7 @@ impl Songbird {
|
||||
client_data.initialised = true;
|
||||
}
|
||||
|
||||
/// Retreives a [`Call`] for the given guild, if one already exists.
|
||||
/// Retrieves a [`Call`] for the given guild, if one already exists.
|
||||
///
|
||||
/// [`Call`]: Call
|
||||
pub fn get<G: Into<GuildId>>(&self, guild_id: G) -> Option<Arc<Mutex<Call>>> {
|
||||
@@ -122,7 +121,7 @@ impl Songbird {
|
||||
map_read.get(&guild_id.into()).cloned()
|
||||
}
|
||||
|
||||
/// Retreives a [`Call`] for the given guild, creating a new one if
|
||||
/// Retrieves a [`Call`] for the given guild, creating a new one if
|
||||
/// none is found.
|
||||
///
|
||||
/// This will not join any calls, or cause connection state to change.
|
||||
@@ -186,11 +185,7 @@ impl Songbird {
|
||||
/// [`Call`]: Call
|
||||
/// [`get`]: Songbird::get
|
||||
#[inline]
|
||||
pub async fn join<C, G>(
|
||||
&self,
|
||||
guild_id: G,
|
||||
channel_id: C,
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<Receiver<ConnectionResult<()>>>)
|
||||
pub async fn join<C, G>(&self, guild_id: G, channel_id: C) -> (Arc<Mutex<Call>>, JoinResult<()>)
|
||||
where
|
||||
C: Into<ChannelId>,
|
||||
G: Into<GuildId>,
|
||||
@@ -203,14 +198,22 @@ impl Songbird {
|
||||
&self,
|
||||
guild_id: GuildId,
|
||||
channel_id: ChannelId,
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<Receiver<ConnectionResult<()>>>) {
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<()>) {
|
||||
let call = self.get_or_insert(guild_id);
|
||||
|
||||
let result = {
|
||||
let stage_1 = {
|
||||
let mut handler = call.lock().await;
|
||||
handler.join(channel_id).await
|
||||
};
|
||||
|
||||
let result = match stage_1 {
|
||||
Ok(chan) => chan
|
||||
.await
|
||||
.map_err(|_| JoinError::Dropped)
|
||||
.and_then(|x| x.map_err(JoinError::from)),
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
|
||||
(call, result)
|
||||
}
|
||||
|
||||
@@ -226,7 +229,7 @@ impl Songbird {
|
||||
&self,
|
||||
guild_id: G,
|
||||
channel_id: C,
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<Receiver<ConnectionInfo>>)
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<ConnectionInfo>)
|
||||
where
|
||||
C: Into<ChannelId>,
|
||||
G: Into<GuildId>,
|
||||
@@ -238,14 +241,19 @@ impl Songbird {
|
||||
&self,
|
||||
guild_id: GuildId,
|
||||
channel_id: ChannelId,
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<Receiver<ConnectionInfo>>) {
|
||||
) -> (Arc<Mutex<Call>>, JoinResult<ConnectionInfo>) {
|
||||
let call = self.get_or_insert(guild_id);
|
||||
|
||||
let result = {
|
||||
let stage_1 = {
|
||||
let mut handler = call.lock().await;
|
||||
handler.join_gateway(channel_id).await
|
||||
};
|
||||
|
||||
let result = match stage_1 {
|
||||
Ok(chan) => chan.await.map_err(|_| JoinError::Dropped),
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
|
||||
(call, result)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user