Docs: Move to new intra-doc links, make events non-exhaustive. (#19)

Far cleaner and more reliable than the old doc-link pattern. Also allowed me to spot some event types and sources which should have been made non_exhaustive.
This commit is contained in:
Kyle Simpson
2020-11-24 19:52:23 +00:00
committed by GitHub
parent 1ada46d24b
commit 94157b12bc
32 changed files with 169 additions and 166 deletions

View File

@@ -12,7 +12,7 @@ pub struct Config {
/// driver is actively connected, but will apply to subsequent /// driver is actively connected, but will apply to subsequent
/// sessions. /// sessions.
/// ///
/// [`CryptoMode::Normal`]: enum.CryptoMode.html#variant.Normal /// [`CryptoMode::Normal`]: CryptoMode::Normal
pub crypto_mode: CryptoMode, pub crypto_mode: CryptoMode,
/// Configures whether decoding and decryption occur for all received packets. /// Configures whether decoding and decryption occur for all received packets.
/// ///
@@ -24,10 +24,10 @@ pub struct Config {
/// Defaults to [`DecodeMode::Decrypt`]. This is due to per-packet decoding costs, /// Defaults to [`DecodeMode::Decrypt`]. This is due to per-packet decoding costs,
/// which most users will not want to pay, but allowing speaking events which are commonly used. /// which most users will not want to pay, but allowing speaking events which are commonly used.
/// ///
/// [`DecodeMode::Decode`]: enum.DecodeMode.html#variant.Decode /// [`DecodeMode::Decode`]: DecodeMode::Decode
/// [`DecodeMode::Decrypt`]: enum.DecodeMode.html#variant.Decrypt /// [`DecodeMode::Decrypt`]: DecodeMode::Decrypt
/// [`DecodeMode::Pass`]: enum.DecodeMode.html#variant.Pass /// [`DecodeMode::Pass`]: DecodeMode::Pass
/// [user speaking events]: ../events/enum.CoreEvent.html#variant.SpeakingUpdate /// [user speaking events]: crate::events::CoreEvent::SpeakingUpdate
pub decode_mode: DecodeMode, pub decode_mode: DecodeMode,
/// Number of concurrently active tracks to allocate memory for. /// Number of concurrently active tracks to allocate memory for.
/// ///

View File

@@ -12,7 +12,7 @@ pub enum DecodeMode {
/// are not present, as they are encrypted. /// are not present, as they are encrypted.
/// This event requires such functionality.* /// This event requires such functionality.*
/// ///
/// [user speaking events]: ../events/enum.CoreEvent.html#variant.SpeakingUpdate /// [user speaking events]: crate::events::CoreEvent::SpeakingUpdate
Pass, Pass,
/// Decrypts the body of each received packet. /// Decrypts the body of each received packet.
/// ///

View File

@@ -125,8 +125,8 @@ impl Driver {
/// ///
/// This can be a source created via [`ffmpeg`] or [`ytdl`]. /// This can be a source created via [`ffmpeg`] or [`ytdl`].
/// ///
/// [`ffmpeg`]: ../input/fn.ffmpeg.html /// [`ffmpeg`]: crate::input::ffmpeg
/// [`ytdl`]: ../input/fn.ytdl.html /// [`ytdl`]: crate::input::ytdl
#[instrument(skip(self))] #[instrument(skip(self))]
pub fn play_source(&mut self, source: Input) -> TrackHandle { pub fn play_source(&mut self, source: Input) -> TrackHandle {
let (player, handle) = super::create_player(source); let (player, handle) = super::create_player(source);
@@ -140,7 +140,7 @@ impl Driver {
/// Unlike [`play_source`], this stops all other sources attached /// Unlike [`play_source`], this stops all other sources attached
/// to the channel. /// to the channel.
/// ///
/// [`play_source`]: #method.play_source /// [`play_source`]: Driver::play_source
#[instrument(skip(self))] #[instrument(skip(self))]
pub fn play_only_source(&mut self, source: Input) -> TrackHandle { pub fn play_only_source(&mut self, source: Input) -> TrackHandle {
let (player, handle) = super::create_player(source); let (player, handle) = super::create_player(source);
@@ -156,9 +156,9 @@ impl Driver {
/// that this allows for direct manipulation of the [`Track`] object /// that this allows for direct manipulation of the [`Track`] object
/// before it is passed over to the voice and mixing contexts. /// before it is passed over to the voice and mixing contexts.
/// ///
/// [`create_player`]: ../tracks/fn.create_player.html /// [`create_player`]: crate::tracks::create_player
/// [`Track`]: ../tracks/struct.Track.html /// [`create_player`]: crate::tracks::Track
/// [`play_source`]: #method.play_source /// [`play_source`]: Driver::play_source
#[instrument(skip(self))] #[instrument(skip(self))]
pub fn play(&mut self, track: Track) { pub fn play(&mut self, track: Track) {
self.send(CoreMessage::AddTrack(track)); self.send(CoreMessage::AddTrack(track));
@@ -171,10 +171,10 @@ impl Driver {
/// channel. Like [`play`], however, this allows for direct manipulation of the /// channel. Like [`play`], however, this allows for direct manipulation of the
/// [`Track`] object before it is passed over to the voice and mixing contexts. /// [`Track`] object before it is passed over to the voice and mixing contexts.
/// ///
/// [`create_player`]: ../tracks/fn.create_player.html /// [`create_player`]: crate::tracks::create_player
/// [`Track`]: ../tracks/struct.Track.html /// [`Track`]: crate::tracks::Track
/// [`play_only_source`]: #method.play_only_source /// [`play_only_source`]: Driver::play_only_source
/// [`play`]: #method.play /// [`play`]: Driver::play
#[instrument(skip(self))] #[instrument(skip(self))]
pub fn play_only(&mut self, track: Track) { pub fn play_only(&mut self, track: Track) {
self.send(CoreMessage::SetTrack(Some(track))); self.send(CoreMessage::SetTrack(Some(track)));
@@ -216,9 +216,9 @@ impl Driver {
/// within the supplied function or closure. *Taking excess time could prevent /// within the supplied function or closure. *Taking excess time could prevent
/// timely sending of packets, causing audio glitches and delays*. /// timely sending of packets, causing audio glitches and delays*.
/// ///
/// [`Track`]: ../tracks/struct.Track.html /// [`Track`]: crate::tracks::Track
/// [`TrackEvent`]: ../events/enum.TrackEvent.html /// [`TrackEvent`]: crate::events::TrackEvent
/// [`EventContext`]: ../events/enum.EventContext.html /// [`EventContext`]: crate::events::EventContext
#[instrument(skip(self, action))] #[instrument(skip(self, action))]
pub fn add_global_event<F: EventHandler + 'static>(&mut self, event: Event, action: F) { pub fn add_global_event<F: EventHandler + 'static>(&mut self, event: Event, action: F) {
self.send(CoreMessage::AddEvent(EventData::new(event, action))); self.send(CoreMessage::AddEvent(EventData::new(event, action)));
@@ -243,8 +243,8 @@ impl Driver {
/// Queue additions should be made via [`enqueue`] and /// Queue additions should be made via [`enqueue`] and
/// [`enqueue_source`]. /// [`enqueue_source`].
/// ///
/// [`enqueue`]: #method.enqueue /// [`enqueue`]: Driver::enqueue
/// [`enqueue_source`]: #method.enqueue_source /// [`enqueue_source`]: Driver::enqueue_source
pub fn queue(&self) -> &TrackQueue { pub fn queue(&self) -> &TrackQueue {
&self.queue &self.queue
} }
@@ -253,7 +253,7 @@ impl Driver {
/// ///
/// Requires the `"builtin-queue"` feature. /// Requires the `"builtin-queue"` feature.
/// ///
/// [`Input`]: ../input/struct.input.html /// [`Input`]: crate::input::Input
pub fn enqueue_source(&mut self, source: Input) { pub fn enqueue_source(&mut self, source: Input) {
let (mut track, _) = tracks::create_player(source); let (mut track, _) = tracks::create_player(source);
self.queue.add_raw(&mut track); self.queue.add_raw(&mut track);
@@ -264,7 +264,7 @@ impl Driver {
/// ///
/// Requires the `"builtin-queue"` feature. /// Requires the `"builtin-queue"` feature.
/// ///
/// [`Track`]: ../tracks/struct.track.html /// [`Track`]: crate::tracks::Track
pub fn enqueue(&mut self, mut track: Track) { pub fn enqueue(&mut self, mut track: Track) {
self.queue.add_raw(&mut track); self.queue.add_raw(&mut track);
self.play(track); self.play(track);

View File

@@ -19,7 +19,7 @@ pub enum JoinError {
NoSender, NoSender,
/// Tried to leave a [`Call`] which was not found. /// Tried to leave a [`Call`] which was not found.
/// ///
/// [`Call`]: ../struct.Call.html /// [`Call`]: crate::Call
NoCall, NoCall,
#[cfg(feature = "serenity")] #[cfg(feature = "serenity")]
/// Serenity-specific WebSocket send error. /// Serenity-specific WebSocket send error.

View File

@@ -8,17 +8,18 @@ use discortp::{rtcp::Rtcp, rtp::Rtp};
/// Information about which tracks or data fired an event. /// Information about which tracks or data fired an event.
/// ///
/// [`Track`] events may be local or global, and have no tracks /// [`Track`] events may be local or global, and have no tracks
/// if fired on the global context via [`Handler::add_global_event`]. /// if fired on the global context via [`Driver::add_global_event`].
/// ///
/// [`Track`]: ../tracks/struct.Track.html /// [`Track`]: crate::tracks::Track
/// [`Handler::add_global_event`]: ../struct.Handler.html#method.add_global_event /// [`Driver::add_global_event`]: crate::driver::Driver::add_global_event
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[non_exhaustive]
pub enum EventContext<'a> { pub enum EventContext<'a> {
/// Track event context, passed to events created via [`TrackHandle::add_event`], /// Track event context, passed to events created via [`TrackHandle::add_event`],
/// [`EventStore::add_event`], or relevant global events. /// [`EventStore::add_event`], or relevant global events.
/// ///
/// [`EventStore::add_event`]: struct.EventStore.html#method.add_event /// [`EventStore::add_event`]: EventStore::add_event
/// [`TrackHandle::add_event`]: ../tracks/struct.TrackHandle.html#method.add_event /// [`TrackHandle::add_event`]: TrackHandle::add_event
Track(&'a [(&'a TrackState, &'a TrackHandle)]), Track(&'a [(&'a TrackState, &'a TrackHandle)]),
/// Speaking state update, typically describing how another voice /// Speaking state update, typically describing how another voice
/// user is transmitting audio data. Clients must send at least one such /// user is transmitting audio data. Clients must send at least one such

View File

@@ -1,11 +1,12 @@
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
/// Voice core events occur on receipt of /// Voice core events occur on receipt of
/// voice packets and telemetry. /// voice packets and telemetry.
/// ///
/// Core events persist while the `action` in [`EventData`] /// Core events persist while the `action` in [`EventData`]
/// returns `None`. /// returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: super::EventData
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum CoreEvent { pub enum CoreEvent {
/// Fired on receipt of a speaking state update from another host. /// Fired on receipt of a speaking state update from another host.
/// ///

View File

@@ -17,10 +17,10 @@ impl EventData {
/// Event handlers will be re-added with their new trigger condition, /// Event handlers will be re-added with their new trigger condition,
/// or removed if [`Cancel`]led /// or removed if [`Cancel`]led
/// ///
/// [`EventContext`]: enum.EventContext.html /// [`EventContext`]: EventContext
/// [`Event`]: enum.Event.html /// [`Event`]: Event
/// [`Delayed`]: enum.Event.html#variant.Delayed /// [`Delayed`]: Event::Delayed
/// [`Cancel`]: enum.Event.html#variant.Cancel /// [`Cancel`]: Event::Cancel
pub fn new<F: EventHandler + 'static>(event: Event, action: F) -> Self { pub fn new<F: EventHandler + 'static>(event: Event, action: F) -> Self {
Self { Self {
event, event,

View File

@@ -12,16 +12,15 @@ pub use self::{context::*, core::*, data::*, store::*, track::*, untimed::*};
use async_trait::async_trait; use async_trait::async_trait;
use std::time::Duration; use std::time::Duration;
#[async_trait]
/// Trait to handle an event which can be fired per-track, or globally. /// Trait to handle an event which can be fired per-track, or globally.
/// ///
/// These may be feasibly reused between several event sources. /// These may be feasibly reused between several event sources.
#[async_trait]
pub trait EventHandler: Send + Sync { pub trait EventHandler: Send + Sync {
/// Respond to one received event. /// Respond to one received event.
async fn act(&self, ctx: &EventContext<'_>) -> Option<Event>; async fn act(&self, ctx: &EventContext<'_>) -> Option<Event>;
} }
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
/// Classes of event which may occur, triggering a handler /// Classes of event which may occur, triggering a handler
/// at the local (track-specific) or global level. /// at the local (track-specific) or global level.
/// ///
@@ -32,7 +31,9 @@ pub trait EventHandler: Send + Sync {
/// ///
/// Event handlers themselves are described in [`EventData::action`]. /// Event handlers themselves are described in [`EventData::action`].
/// ///
/// [`EventData::action`]: struct.EventData.html#method.action /// [`EventData::action`]: EventData::action
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum Event { pub enum Event {
/// Periodic events rely upon two parameters: a *period* /// Periodic events rely upon two parameters: a *period*
/// and an optional *phase*. /// and an optional *phase*.
@@ -41,7 +42,7 @@ pub enum Event {
/// in one *period*. Periodic events repeat automatically /// in one *period*. Periodic events repeat automatically
/// so long as the `action` in [`EventData`] returns `None`. /// so long as the `action` in [`EventData`] returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
Periodic(Duration, Option<Duration>), Periodic(Duration, Option<Duration>),
/// Delayed events rely upon a *delay* parameter, and /// Delayed events rely upon a *delay* parameter, and
/// fire one *delay* after the audio context processes them. /// fire one *delay* after the audio context processes them.
@@ -49,7 +50,7 @@ pub enum Event {
/// Delayed events are automatically removed once fired, /// Delayed events are automatically removed once fired,
/// so long as the `action` in [`EventData`] returns `None`. /// so long as the `action` in [`EventData`] returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
Delayed(Duration), Delayed(Duration),
/// Track events correspond to certain actions or changes /// Track events correspond to certain actions or changes
/// of state, such as a track finishing, looping, or being /// of state, such as a track finishing, looping, or being
@@ -58,7 +59,7 @@ pub enum Event {
/// Track events persist while the `action` in [`EventData`] /// Track events persist while the `action` in [`EventData`]
/// returns `None`. /// returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
Track(TrackEvent), Track(TrackEvent),
/// Core events /// Core events
/// ///
@@ -66,7 +67,7 @@ pub enum Event {
/// returns `None`. Core events **must** be applied globally, /// returns `None`. Core events **must** be applied globally,
/// as attaching them to a track is a no-op. /// as attaching them to a track is a no-op.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
Core(CoreEvent), Core(CoreEvent),
/// Cancels the event, if it was intended to persist. /// Cancels the event, if it was intended to persist.
Cancel, Cancel,

View File

@@ -15,7 +15,7 @@ use tracing::info;
/// Timed events are stored in a binary heap for fast selection, and have custom `Eq`, /// Timed events are stored in a binary heap for fast selection, and have custom `Eq`,
/// `Ord`, etc. implementations to support (only) this. /// `Ord`, etc. implementations to support (only) this.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
pub struct EventStore { pub struct EventStore {
timed: BinaryHeap<EventData>, timed: BinaryHeap<EventData>,
untimed: HashMap<UntimedEvent, Vec<EventData>>, untimed: HashMap<UntimedEvent, Vec<EventData>>,
@@ -33,7 +33,7 @@ impl EventStore {
/// This is usually automatically installed by the driver once /// This is usually automatically installed by the driver once
/// a track has been registered. /// a track has been registered.
/// ///
/// [`Track`]: ../tracks/struct.Track.html /// [`Track`]: crate::tracks::Track
pub fn new_local() -> Self { pub fn new_local() -> Self {
EventStore { EventStore {
local_only: true, local_only: true,
@@ -45,7 +45,7 @@ impl EventStore {
/// ///
/// Updates `evt` according to [`EventData::compute_activation`]. /// Updates `evt` according to [`EventData::compute_activation`].
/// ///
/// [`EventData::compute_activation`]: struct.EventData.html#method.compute_activation /// [`EventData::compute_activation`]: EventData::compute_activation
pub fn add_event(&mut self, mut evt: EventData, now: Duration) { pub fn add_event(&mut self, mut evt: EventData, now: Duration) {
evt.compute_activation(now); evt.compute_activation(now);

View File

@@ -1,4 +1,3 @@
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
/// Track events correspond to certain actions or changes /// Track events correspond to certain actions or changes
/// of state, such as a track finishing, looping, or being /// of state, such as a track finishing, looping, or being
/// manually stopped. Voice core events occur on receipt of /// manually stopped. Voice core events occur on receipt of
@@ -7,7 +6,9 @@
/// Track events persist while the `action` in [`EventData`] /// Track events persist while the `action` in [`EventData`]
/// returns `None`. /// returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: super::EventData
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum TrackEvent { pub enum TrackEvent {
/// The attached track has ended. /// The attached track has ended.
End, End,

View File

@@ -1,12 +1,13 @@
use super::*; use super::*;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
/// Track and voice core events. /// Track and voice core events.
/// ///
/// Untimed events persist while the `action` in [`EventData`] /// Untimed events persist while the `action` in [`EventData`]
/// returns `None`. /// returns `None`.
/// ///
/// [`EventData`]: struct.EventData.html /// [`EventData`]: EventData
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum UntimedEvent { pub enum UntimedEvent {
/// Untimed events belonging to a track, such as state changes, end, or loops. /// Untimed events belonging to a track, such as state changes, end, or loops.
Track(TrackEvent), Track(TrackEvent),

View File

@@ -29,8 +29,7 @@ enum Return {
/// If the `"driver"` feature is enabled, then a Call exposes all control methods of /// If the `"driver"` feature is enabled, then a Call exposes all control methods of
/// [`Driver`] via `Deref(Mut)`. /// [`Driver`] via `Deref(Mut)`.
/// ///
/// [`Driver`]: driver/struct.Driver.html /// [`Driver`]: struct@Driver
/// [`Shard`]: ../gateway/struct.Shard.html
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Call { pub struct Call {
connection: Option<(ChannelId, ConnectionProgress, Return)>, connection: Option<(ChannelId, ConnectionProgress, Return)>,
@@ -45,11 +44,14 @@ pub struct Call {
/// Whether the current handler is set to mute voice connections. /// Whether the current handler is set to mute voice connections.
self_mute: bool, self_mute: bool,
user_id: UserId, user_id: UserId,
/// Will be set when a `Call` is made via the [`new`][`Call::new`] /// Will be set when a `Call` is made via the [`new`]
/// method. /// method.
/// ///
/// When set via [`standalone`][`Call::standalone`], it will not be /// When set via [`standalone`](`Call::standalone`), it will not be
/// present. /// present.
///
/// [`new`]: Call::new
/// [`standalone`]: Call::standalone
ws: Option<Shard>, ws: Option<Shard>,
} }
@@ -153,7 +155,7 @@ impl Call {
/// **Note**: If the `Call` was created via [`standalone`], then this /// **Note**: If the `Call` was created via [`standalone`], then this
/// will _only_ update whether the connection is internally deafened. /// will _only_ update whether the connection is internally deafened.
/// ///
/// [`standalone`]: #method.standalone /// [`standalone`]: Call::standalone
#[instrument(skip(self))] #[instrument(skip(self))]
pub async fn deafen(&mut self, deaf: bool) -> JoinResult<()> { pub async fn deafen(&mut self, deaf: bool) -> JoinResult<()> {
self.self_deaf = deaf; self.self_deaf = deaf;
@@ -217,7 +219,7 @@ impl Call {
/// will _only_ update whether the connection is internally connected to a /// will _only_ update whether the connection is internally connected to a
/// voice channel. /// voice channel.
/// ///
/// [`standalone`]: #method.standalone /// [`standalone`]: Call::standalone
#[instrument(skip(self))] #[instrument(skip(self))]
pub async fn leave(&mut self) -> JoinResult<()> { pub async fn leave(&mut self) -> JoinResult<()> {
// Only send an update if we were in a voice channel. // Only send an update if we were in a voice channel.
@@ -237,7 +239,7 @@ impl Call {
/// **Note**: If the `Call` was created via [`standalone`], then this /// **Note**: If the `Call` was created via [`standalone`], then this
/// will _only_ update whether the connection is internally muted. /// will _only_ update whether the connection is internally muted.
/// ///
/// [`standalone`]: #method.standalone /// [`standalone`]: Call::standalone
#[instrument(skip(self))] #[instrument(skip(self))]
pub async fn mute(&mut self, mute: bool) -> JoinResult<()> { pub async fn mute(&mut self, mute: bool) -> JoinResult<()> {
self.self_mute = mute; self.self_mute = mute;
@@ -259,11 +261,7 @@ impl Call {
/// You should only need to use this if you initialized the `Call` via /// You should only need to use this if you initialized the `Call` via
/// [`standalone`]. /// [`standalone`].
/// ///
/// Refer to the documentation for [`connect`] for when this will /// [`standalone`]: Call::standalone
/// automatically connect to a voice channel.
///
/// [`connect`]: #method.connect
/// [`standalone`]: #method.standalone
#[instrument(skip(self, token))] #[instrument(skip(self, token))]
pub fn update_server(&mut self, endpoint: String, token: String) { pub fn update_server(&mut self, endpoint: String, token: String) {
let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() { let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() {
@@ -282,11 +280,7 @@ impl Call {
/// You should only need to use this if you initialized the `Call` via /// You should only need to use this if you initialized the `Call` via
/// [`standalone`]. /// [`standalone`].
/// ///
/// refer to the documentation for [`connect`] for when this will /// [`standalone`]: Call::standalone
/// automatically connect to a voice channel.
///
/// [`connect`]: #method.connect
/// [`standalone`]: #method.standalone
#[instrument(skip(self))] #[instrument(skip(self))]
pub fn update_state(&mut self, session_id: String) { pub fn update_state(&mut self, session_id: String) {
let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() { let try_conn = if let Some((_, ref mut progress, _)) = self.connection.as_mut() {
@@ -304,7 +298,7 @@ impl Call {
/// ///
/// Does nothing if initialized via [`standalone`]. /// Does nothing if initialized via [`standalone`].
/// ///
/// [`standalone`]: #method.standalone /// [`standalone`]: Call::standalone
#[instrument(skip(self))] #[instrument(skip(self))]
async fn update(&mut self) -> JoinResult<()> { async fn update(&mut self) -> JoinResult<()> {
if let Some(ws) = self.ws.as_mut() { if let Some(ws) = self.ws.as_mut() {

View File

@@ -43,9 +43,9 @@ use tracing::{debug, trace};
/// retrieved as **compressed Opus audio**. There is an associated memory cost, /// retrieved as **compressed Opus audio**. There is an associated memory cost,
/// but this is far smaller than using a [`Memory`]. /// but this is far smaller than using a [`Memory`].
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`Memory`]: struct.Memory.html /// [`Memory`]: super::Memory
/// [`Restartable`]: ../struct.Restartable.html /// [`Restartable`]: crate::input::restartable::Restartable
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Compressed { pub struct Compressed {
/// Inner shared bytestore. /// Inner shared bytestore.
@@ -59,7 +59,7 @@ pub struct Compressed {
impl Compressed { impl Compressed {
/// Wrap an existing [`Input`] with an in-memory store, compressed using Opus. /// Wrap an existing [`Input`] with an in-memory store, compressed using Opus.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration /// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration
pub fn new(source: Input, bitrate: Bitrate) -> Result<Self> { pub fn new(source: Input, bitrate: Bitrate) -> Result<Self> {
Self::with_config(source, bitrate, None) Self::with_config(source, bitrate, None)
@@ -69,10 +69,10 @@ impl Compressed {
/// ///
/// `config.length_hint` may be used to control the size of the initial chunk, preventing /// `config.length_hint` may be used to control the size of the initial chunk, preventing
/// needless allocations and copies. If this is not present, the value specified in /// needless allocations and copies. If this is not present, the value specified in
/// `source`'s [`Metadata.duration`] will be used. /// `source`'s [`Metadata::duration`] will be used.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration /// [`Metadata::duration`]: crate::input::Metadata::duration
pub fn with_config(source: Input, bitrate: Bitrate, config: Option<Config>) -> Result<Self> { pub fn with_config(source: Input, bitrate: Bitrate, config: Option<Config>) -> Result<Self> {
let channels = if source.stereo { let channels = if source.stereo {
Channels::Stereo Channels::Stereo
@@ -92,8 +92,8 @@ impl Compressed {
/// `length_hint` functions as in [`new`]. This function's behaviour is undefined if your encoder /// `length_hint` functions as in [`new`]. This function's behaviour is undefined if your encoder
/// has a different sample rate than 48kHz, and if the decoder has a different channel count from the source. /// has a different sample rate than 48kHz, and if the decoder has a different channel count from the source.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`new`]: #method.new /// [`new`]: Compressed::new
pub fn with_encoder( pub fn with_encoder(
mut source: Input, mut source: Input,
encoder: OpusEncoder, encoder: OpusEncoder,
@@ -154,7 +154,7 @@ impl From<Compressed> for Input {
/// ///
/// Created and managed by [`Compressed`]. /// Created and managed by [`Compressed`].
/// ///
/// [`Compressed`]: struct.Compressed.html /// [`Compressed`]: Compressed
#[derive(Debug)] #[derive(Debug)]
pub struct OpusCompressor { pub struct OpusCompressor {
encoder: OpusEncoder, encoder: OpusEncoder,

View File

@@ -25,9 +25,9 @@ use streamcatcher::{Catcher, Config};
/// cost of audio processing. This is a significant *3 Mbps (375 kiB/s)*, /// cost of audio processing. This is a significant *3 Mbps (375 kiB/s)*,
/// or 131 MiB of RAM for a 6 minute song. /// or 131 MiB of RAM for a 6 minute song.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`Compressed`]: struct.Compressed.html /// [`Compressed`]: super::Compressed
/// [`Restartable`]: ../struct.Restartable.html /// [`Restartable`]: crate::input::restartable::Restartable
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Memory { pub struct Memory {
/// Inner shared bytestore. /// Inner shared bytestore.
@@ -45,7 +45,7 @@ pub struct Memory {
impl Memory { impl Memory {
/// Wrap an existing [`Input`] with an in-memory store with the same codec and framing. /// Wrap an existing [`Input`] with an in-memory store with the same codec and framing.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
pub fn new(source: Input) -> Result<Self> { pub fn new(source: Input) -> Result<Self> {
Self::with_config(source, None) Self::with_config(source, None)
} }
@@ -54,10 +54,10 @@ impl Memory {
/// ///
/// `length_hint` may be used to control the size of the initial chunk, preventing /// `length_hint` may be used to control the size of the initial chunk, preventing
/// needless allocations and copies. If this is not present, the value specified in /// needless allocations and copies. If this is not present, the value specified in
/// `source`'s [`Metadata.duration`] will be used, assuming that the source is uncompressed. /// `source`'s [`Metadata::duration`] will be used, assuming that the source is uncompressed.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
/// [`Metadata.duration`]: ../struct.Metadata.html#structfield.duration /// [`Metadata::duration`]: crate::input::Metadata::duration
pub fn with_config(mut source: Input, config: Option<Config>) -> Result<Self> { pub fn with_config(mut source: Input, config: Option<Config>) -> Result<Self> {
let stereo = source.stereo; let stereo = source.stereo;
let kind = (&source.kind).into(); let kind = (&source.kind).into();

View File

@@ -9,7 +9,7 @@ use std::{fmt::Debug, mem};
/// State used to decode input bytes of an [`Input`]. /// State used to decode input bytes of an [`Input`].
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Codec { pub enum Codec {
@@ -18,19 +18,19 @@ pub enum Codec {
/// ///
/// Must be combined with a non-[`Raw`] container. /// Must be combined with a non-[`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
Opus(OpusDecoderState), Opus(OpusDecoderState),
/// The inner bytestream is encoded using raw `i16` samples. /// The inner bytestream is encoded using raw `i16` samples.
/// ///
/// Must be combined with a [`Raw`] container. /// Must be combined with a [`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
Pcm, Pcm,
/// The inner bytestream is encoded using raw `f32` samples. /// The inner bytestream is encoded using raw `f32` samples.
/// ///
/// Must be combined with a [`Raw`] container. /// Must be combined with a [`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
FloatPcm, FloatPcm,
} }
@@ -48,7 +48,7 @@ impl From<&Codec> for CodecType {
/// Type of data being passed into an [`Input`]. /// Type of data being passed into an [`Input`].
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: Input
#[non_exhaustive] #[non_exhaustive]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum CodecType { pub enum CodecType {
@@ -56,19 +56,19 @@ pub enum CodecType {
/// ///
/// Must be combined with a non-[`Raw`] container. /// Must be combined with a non-[`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
Opus, Opus,
/// The inner bytestream is encoded using raw `i16` samples. /// The inner bytestream is encoded using raw `i16` samples.
/// ///
/// Must be combined with a [`Raw`] container. /// Must be combined with a [`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
Pcm, Pcm,
/// The inner bytestream is encoded using raw `f32` samples. /// The inner bytestream is encoded using raw `f32` samples.
/// ///
/// Must be combined with a [`Raw`] container. /// Must be combined with a [`Raw`] container.
/// ///
/// [`Raw`]: ../enum.Container.html#variant.Raw /// [`Raw`]: Container::Raw
FloatPcm, FloatPcm,
} }

View File

@@ -4,7 +4,7 @@ use parking_lot::Mutex;
use std::sync::Arc; use std::sync::Arc;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
/// Inner state /// Inner state used to decode Opus input sources.
pub struct OpusDecoderState { pub struct OpusDecoderState {
/// Inner decoder used to convert opus frames into a stream of samples. /// Inner decoder used to convert opus frames into a stream of samples.
pub decoder: Arc<Mutex<OpusDecoder>>, pub decoder: Arc<Mutex<OpusDecoder>>,

View File

@@ -7,7 +7,7 @@ use streamcatcher::CatcherError;
/// An error returned when creating a new [`Input`]. /// An error returned when creating a new [`Input`].
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: crate::input::Input
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum Error { pub enum Error {
@@ -71,7 +71,7 @@ impl From<OpusError> for Error {
/// An error returned from the [`dca`] method. /// An error returned from the [`dca`] method.
/// ///
/// [`dca`]: ../fn.dca.html /// [`dca`]: crate::input::dca
#[derive(Debug)] #[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum DcaError { pub enum DcaError {
@@ -89,5 +89,5 @@ pub enum DcaError {
/// Convenience type for fallible return of [`Input`]s. /// Convenience type for fallible return of [`Input`]s.
/// ///
/// [`Input`]: ../struct.Input.html /// [`Input`]: crate::input::Input
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;

View File

@@ -71,7 +71,9 @@ pub(crate) async fn _ffmpeg(path: &OsStr) -> Result<Input> {
/// "pcm_s16le", /// "pcm_s16le",
/// "-", /// "-",
/// ])); /// ]));
///``` /// ```
///
/// [`ffmpeg`]: ffmpeg
pub async fn ffmpeg_optioned<P: AsRef<OsStr>>( pub async fn ffmpeg_optioned<P: AsRef<OsStr>>(
path: P, path: P,
pre_input_args: &[&str], pre_input_args: &[&str],

View File

@@ -4,7 +4,7 @@ use std::time::Duration;
/// Information about an [`Input`] source. /// Information about an [`Input`] source.
/// ///
/// [`Input`]: struct.Input.html /// [`Input`]: crate::input::Input
#[derive(Clone, Debug, Default, Eq, PartialEq)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Metadata { pub struct Metadata {
/// The title of this stream. /// The title of this stream.
@@ -95,7 +95,7 @@ impl Metadata {
} }
} }
/// Use `youtube-dl` to extract metadata for an online resource. /// Use `youtube-dl`'s JSON output for metadata for an online resource.
pub fn from_ytdl_output(value: Value) -> Self { pub fn from_ytdl_output(value: Value) -> Self {
let obj = value.as_object(); let obj = value.as_object();

View File

@@ -20,13 +20,13 @@
//! * its [`Input`] [meets the promises described herein](codec/struct.OpusDecoderState.html#structfield.allow_passthrough), //! * its [`Input`] [meets the promises described herein](codec/struct.OpusDecoderState.html#structfield.allow_passthrough),
//! * and that track's volume is set to `1.0`. //! * and that track's volume is set to `1.0`.
//! //!
//! [`Input`]: struct.Input.html //! [`Input`]: Input
//! [`Reader`]: reader/enum.Reader.html //! [`Reader`]: reader::Reader
//! [`Container`]: enum.Container.html //! [`Container`]: Container
//! [`Codec`]: codec/enum.Codec.html //! [`Codec`]: Codec
//! [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html //! [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
//! [`Compressed`]: cached/struct.Compressed.html //! [`Compressed`]: cached::Compressed
//! [`dca`]: fn.dca.html //! [`dca`]: dca()
pub mod cached; pub mod cached;
mod child; mod child;
@@ -80,8 +80,8 @@ use tracing::{debug, error};
/// ///
/// See the [module root] for more information. /// See the [module root] for more information.
/// ///
/// [`Reader`]: enum.Reader.html /// [`Reader`]: Reader
/// [module root]: index.html /// [module root]: super
#[derive(Debug)] #[derive(Debug)]
pub struct Input { pub struct Input {
/// Information about the played source. /// Information about the played source.
@@ -130,7 +130,7 @@ impl Input {
/// Returns whether the inner [`Reader`] implements [`Seek`]. /// Returns whether the inner [`Reader`] implements [`Seek`].
/// ///
/// [`Reader`]: reader/enum.Reader.html /// [`Reader`]: reader::Reader
/// [`Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html /// [`Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html
pub fn is_seekable(&self) -> bool { pub fn is_seekable(&self) -> bool {
self.reader.is_seekable() self.reader.is_seekable()
@@ -143,7 +143,7 @@ impl Input {
/// Returns the type of the inner [`Codec`]. /// Returns the type of the inner [`Codec`].
/// ///
/// [`Codec`]: codec/enum.Codec.html /// [`Codec`]: Codec
pub fn get_type(&self) -> CodecType { pub fn get_type(&self) -> CodecType {
(&self.kind).into() (&self.kind).into()
} }

View File

@@ -23,14 +23,14 @@ use streamcatcher::{Catcher, TxCatcher};
/// Users may define their own data sources using [`Extension`] /// Users may define their own data sources using [`Extension`]
/// and [`ExtensionSeek`]. /// and [`ExtensionSeek`].
/// ///
/// [`Extension`]: #variant.Extension /// [`Extension`]: Reader::Extension
/// [`ExtensionSeek`]: #variant.ExtensionSeek /// [`ExtensionSeek`]: Reader::ExtensionSeek
pub enum Reader { pub enum Reader {
/// Piped output of another program (i.e., [`ffmpeg`]). /// Piped output of another program (i.e., [`ffmpeg`]).
/// ///
/// Does not support seeking. /// Does not support seeking.
/// ///
/// [`ffmpeg`]: ../fn.ffmpeg.html /// [`ffmpeg`]: super::ffmpeg
Pipe(BufReader<ChildContainer>), Pipe(BufReader<ChildContainer>),
/// A cached, raw in-memory store, provided by Songbird. /// A cached, raw in-memory store, provided by Songbird.
/// ///

View File

@@ -37,9 +37,9 @@ type RecreateChannel = Receiver<Result<(Box<Input>, Recreator)>>;
/// cannot be spared. Forward seeks will drain the track until reaching /// cannot be spared. Forward seeks will drain the track until reaching
/// the desired timestamp. /// the desired timestamp.
/// ///
/// [`Input`]: struct.Input.html /// [`Input`]: Input
/// [`Memory`]: cached/struct.Memory.html /// [`Memory`]: cached::Memory
/// [`Compressed`]: cached/struct.Compressed.html /// [`Compressed`]: cached::Compressed
pub struct Restartable { pub struct Restartable {
async_handle: Option<Handle>, async_handle: Option<Handle>,
awaiting_source: Option<RecreateChannel>, awaiting_source: Option<RecreateChannel>,
@@ -89,7 +89,7 @@ impl Restartable {
/// Trait used to create an instance of a [`Reader`] at instantiation and when /// Trait used to create an instance of a [`Reader`] at instantiation and when
/// a backwards seek is needed. /// a backwards seek is needed.
/// ///
/// [`Reader`]: ../reader/enum.Reader.html /// [`Reader`]: reader::Reader
#[async_trait] #[async_trait]
pub trait Restart { pub trait Restart {
/// Tries to create a replacement source. /// Tries to create a replacement source.

View File

@@ -3,6 +3,7 @@
html_favicon_url = "https://raw.githubusercontent.com/serenity-rs/songbird/current/songbird-ico.png" html_favicon_url = "https://raw.githubusercontent.com/serenity-rs/songbird/current/songbird-ico.png"
)] )]
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(broken_intra_doc_links)]
//! ![project logo][logo] //! ![project logo][logo]
//! //!
//! Songbird is an async, cross-library compatible voice system for Discord, written in Rust. //! Songbird is an async, cross-library compatible voice system for Discord, written in Rust.
@@ -33,7 +34,7 @@
//! [twilight]: https://github.com/twilight-rs/twilight //! [twilight]: https://github.com/twilight-rs/twilight
//! [this crate's examples directory]: https://github.com/serenity-rs/songbird/tree/current/examples //! [this crate's examples directory]: https://github.com/serenity-rs/songbird/tree/current/examples
//! ["Black-Capped Chickadee"]: https://www.oldbookillustrations.com/illustrations/black-capped-chickadee/ //! ["Black-Capped Chickadee"]: https://www.oldbookillustrations.com/illustrations/black-capped-chickadee/
//! [`ConnectionInfo`]: struct.ConnectionInfo.html //! [`ConnectionInfo`]: struct@ConnectionInfo
//! [lavalink]: https://github.com/Frederikam/Lavalink //! [lavalink]: https://github.com/Frederikam/Lavalink
pub mod constants; pub mod constants;

View File

@@ -41,7 +41,7 @@ struct ClientData {
/// This manager transparently maps guild state and a source of shard information /// This manager transparently maps guild state and a source of shard information
/// into individual calls, and forwards state updates which affect call state. /// into individual calls, and forwards state updates which affect call state.
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
#[derive(Debug)] #[derive(Debug)]
pub struct Songbird { pub struct Songbird {
client_data: PRwLock<ClientData>, client_data: PRwLock<ClientData>,
@@ -58,7 +58,7 @@ impl Songbird {
/// ///
/// This must be [registered] after creation. /// This must be [registered] after creation.
/// ///
/// [registered]: serenity/fn.register_with.html /// [registered]: crate::serenity::register_with
pub fn serenity() -> Arc<Self> { pub fn serenity() -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
client_data: Default::default(), client_data: Default::default(),
@@ -77,7 +77,7 @@ impl Songbird {
/// users are responsible for passing in any events using /// users are responsible for passing in any events using
/// [`process`]. /// [`process`].
/// ///
/// [`process`]: #method.process /// [`process`]: Songbird::process
pub fn twilight<U>(cluster: Cluster, shard_count: u64, user_id: U) -> Arc<Self> pub fn twilight<U>(cluster: Cluster, shard_count: u64, user_id: U) -> Arc<Self>
where where
U: Into<UserId>, U: Into<UserId>,
@@ -101,7 +101,7 @@ impl Songbird {
/// If this struct is already initialised (e.g., from [`::twilight`]), /// If this struct is already initialised (e.g., from [`::twilight`]),
/// or a previous call, then this function is a no-op. /// or a previous call, then this function is a no-op.
/// ///
/// [`::twilight`]: #method.twilight /// [`::twilight`]: Songbird::twilight
pub fn initialise_client_data<U: Into<UserId>>(&self, shard_count: u64, user_id: U) { pub fn initialise_client_data<U: Into<UserId>>(&self, shard_count: u64, user_id: U) {
let mut client_data = self.client_data.write(); let mut client_data = self.client_data.write();
@@ -116,7 +116,7 @@ impl Songbird {
/// Retreives a [`Call`] for the given guild, if one already exists. /// Retreives a [`Call`] for the given guild, if one already exists.
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
pub fn get<G: Into<GuildId>>(&self, guild_id: G) -> Option<Arc<Mutex<Call>>> { pub fn get<G: Into<GuildId>>(&self, guild_id: G) -> Option<Arc<Mutex<Call>>> {
let map_read = self.calls.read(); let map_read = self.calls.read();
map_read.get(&guild_id.into()).cloned() map_read.get(&guild_id.into()).cloned()
@@ -127,7 +127,7 @@ impl Songbird {
/// ///
/// This will not join any calls, or cause connection state to change. /// This will not join any calls, or cause connection state to change.
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
pub fn get_or_insert(&self, guild_id: GuildId) -> Arc<Mutex<Call>> { pub fn get_or_insert(&self, guild_id: GuildId) -> Arc<Mutex<Call>> {
self.get(guild_id).unwrap_or_else(|| { self.get(guild_id).unwrap_or_else(|| {
let mut map_read = self.calls.write(); let mut map_read = self.calls.write();
@@ -183,8 +183,8 @@ impl Songbird {
/// If you _only_ need to retrieve the handler for a target, then use /// If you _only_ need to retrieve the handler for a target, then use
/// [`get`]. /// [`get`].
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
/// [`get`]: #method.get /// [`get`]: Songbird::get
#[inline] #[inline]
pub async fn join<C, G>( pub async fn join<C, G>(
&self, &self,
@@ -220,7 +220,7 @@ impl Songbird {
/// This method returns the handle and the connection info needed for other libraries /// This method returns the handle and the connection info needed for other libraries
/// or drivers, such as lavalink, and does not actually start or run a voice call. /// or drivers, such as lavalink, and does not actually start or run a voice call.
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
#[inline] #[inline]
pub async fn join_gateway<C, G>( pub async fn join_gateway<C, G>(
&self, &self,
@@ -257,9 +257,9 @@ impl Songbird {
/// This is a wrapper around [getting][`get`] a handler and calling /// This is a wrapper around [getting][`get`] a handler and calling
/// [`leave`] on it. /// [`leave`] on it.
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
/// [`get`]: #method.get /// [`get`]: Songbird::get
/// [`leave`]: struct.Call.html#method.leave /// [`leave`]: Call::leave
#[inline] #[inline]
pub async fn leave<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> { pub async fn leave<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> {
self._leave(guild_id.into()).await self._leave(guild_id.into()).await
@@ -282,7 +282,7 @@ impl Songbird {
/// An Err(...) value implies that the gateway could not be contacted, /// An Err(...) value implies that the gateway could not be contacted,
/// and that leaving should be attempted again later (i.e., after reconnect). /// and that leaving should be attempted again later (i.e., after reconnect).
/// ///
/// [`Call`]: struct.Call.html /// [`Call`]: Call
#[inline] #[inline]
pub async fn remove<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> { pub async fn remove<G: Into<GuildId>>(&self, guild_id: G) -> JoinResult<()> {
self._remove(guild_id.into()).await self._remove(guild_id.into()).await

View File

@@ -13,7 +13,7 @@ use std::sync::Arc;
/// Zero-size type used to retrieve the registered [`Songbird`] instance /// Zero-size type used to retrieve the registered [`Songbird`] instance
/// from serenity's inner TypeMap. /// from serenity's inner TypeMap.
/// ///
/// [`Songbird`]: ../struct.Songbird.html /// [`Songbird`]: Songbird
pub struct SongbirdKey; pub struct SongbirdKey;
impl TypeMapKey for SongbirdKey { impl TypeMapKey for SongbirdKey {
@@ -54,7 +54,7 @@ pub trait SerenityInit {
/// Registers a new Songbird voice system with serenity, storing it for easy /// Registers a new Songbird voice system with serenity, storing it for easy
/// access via [`get`]. /// access via [`get`].
/// ///
/// [`get`]: fn.get.html /// [`get`]: get
fn register_songbird(self) -> Self; fn register_songbird(self) -> Self;
/// Registers a given Songbird voice system with serenity, as above. /// Registers a given Songbird voice system with serenity, as above.
fn register_songbird_with(self, voice: Arc<Songbird>) -> Self; fn register_songbird_with(self, voice: Arc<Songbird>) -> Self;

View File

@@ -6,8 +6,9 @@ use tokio::sync::oneshot::Sender as OneshotSender;
/// A request from external code using a [`TrackHandle`] to modify /// A request from external code using a [`TrackHandle`] to modify
/// or act upon an [`Track`] object. /// or act upon an [`Track`] object.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
/// [`TrackHandle`]: struct.TrackHandle.html /// [`TrackHandle`]: TrackHandle
#[non_exhaustive]
pub enum TrackCommand { pub enum TrackCommand {
/// Set the track's play_mode to play/resume. /// Set the track's play_mode to play/resume.
Play, Play,

View File

@@ -15,7 +15,7 @@ use uuid::Uuid;
/// the underlying [`Track`] object has been discarded. Those which aren't refer /// the underlying [`Track`] object has been discarded. Those which aren't refer
/// to immutable properties of the underlying stream. /// to immutable properties of the underlying stream.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
pub struct TrackHandle { pub struct TrackHandle {
command_channel: UnboundedSender<TrackCommand>, command_channel: UnboundedSender<TrackCommand>,
seekable: bool, seekable: bool,
@@ -26,7 +26,7 @@ impl TrackHandle {
/// Creates a new handle, using the given command sink and hint as to whether /// Creates a new handle, using the given command sink and hint as to whether
/// the underlying [`Input`] supports seek operations. /// the underlying [`Input`] supports seek operations.
/// ///
/// [`Input`]: ../input/struct.Input.html /// [`Input`]: crate::input::Input
pub fn new(command_channel: UnboundedSender<TrackCommand>, seekable: bool, uuid: Uuid) -> Self { pub fn new(command_channel: UnboundedSender<TrackCommand>, seekable: bool, uuid: Uuid) -> Self {
Self { Self {
command_channel, command_channel,
@@ -50,7 +50,7 @@ impl TrackHandle {
/// This is *final*, and will cause the audio context to fire /// This is *final*, and will cause the audio context to fire
/// a [`TrackEvent::End`] event. /// a [`TrackEvent::End`] event.
/// ///
/// [`TrackEvent::End`]: ../events/enum.TrackEvent.html#variant.End /// [`TrackEvent::End`]: crate::events::TrackEvent::End
pub fn stop(&self) -> TrackResult { pub fn stop(&self) -> TrackResult {
self.send(TrackCommand::Stop) self.send(TrackCommand::Stop)
} }
@@ -62,11 +62,11 @@ impl TrackHandle {
/// Denotes whether the underlying [`Input`] stream is compatible with arbitrary seeking. /// Denotes whether the underlying [`Input`] stream is compatible with arbitrary seeking.
/// ///
/// If this returns `false`, all calls to [`seek`] will fail, and the track is /// If this returns `false`, all calls to [`seek_time`] will fail, and the track is
/// incapable of looping. /// incapable of looping.
/// ///
/// [`seek`]: #method.seek /// [`seek_time`]: TrackHandle::seek_time
/// [`Input`]: ../input/struct.Input.html /// [`Input`]: crate::input::Input
pub fn is_seekable(&self) -> bool { pub fn is_seekable(&self) -> bool {
self.seekable self.seekable
} }
@@ -76,7 +76,7 @@ impl TrackHandle {
/// If the underlying [`Input`] does not support this behaviour, /// If the underlying [`Input`] does not support this behaviour,
/// then all calls will fail. /// then all calls will fail.
/// ///
/// [`Input`]: ../input/struct.Input.html /// [`Input`]: crate::input::Input
pub fn seek_time(&self, position: Duration) -> TrackResult { pub fn seek_time(&self, position: Duration) -> TrackResult {
if self.seekable { if self.seekable {
self.send(TrackCommand::Seek(position)) self.send(TrackCommand::Seek(position))
@@ -91,8 +91,8 @@ impl TrackHandle {
/// within the supplied function or closure. *Taking excess time could prevent /// within the supplied function or closure. *Taking excess time could prevent
/// timely sending of packets, causing audio glitches and delays*. /// timely sending of packets, causing audio glitches and delays*.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
/// [`EventContext::Track`]: ../events/enum.EventContext.html#variant.Track /// [`EventContext::Track`]: crate::events::EventContext::Track
pub fn add_event<F: EventHandler + 'static>(&self, event: Event, action: F) -> TrackResult { pub fn add_event<F: EventHandler + 'static>(&self, event: Event, action: F) -> TrackResult {
let cmd = TrackCommand::AddEvent(EventData::new(event, action)); let cmd = TrackCommand::AddEvent(EventData::new(event, action));
if event.is_global_only() { if event.is_global_only() {
@@ -108,7 +108,7 @@ impl TrackHandle {
/// within the supplied function or closure. *Taking excess time could prevent /// within the supplied function or closure. *Taking excess time could prevent
/// timely sending of packets, causing audio glitches and delays*. /// timely sending of packets, causing audio glitches and delays*.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
pub fn action<F>(&self, action: F) -> TrackResult pub fn action<F>(&self, action: F) -> TrackResult
where where
F: FnOnce(&mut Track) + Send + Sync + 'static, F: FnOnce(&mut Track) + Send + Sync + 'static,
@@ -160,7 +160,7 @@ impl TrackHandle {
#[inline] #[inline]
/// Send a raw command to the [`Track`] object. /// Send a raw command to the [`Track`] object.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
pub fn send(&self, cmd: TrackCommand) -> TrackResult { pub fn send(&self, cmd: TrackCommand) -> TrackResult {
self.command_channel.send(cmd) self.command_channel.send(cmd)
} }

View File

@@ -1,7 +1,7 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
/// Looping behaviour for a [`Track`]. /// Looping behaviour for a [`Track`].
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: struct.Track.html
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum LoopState { pub enum LoopState {
/// Track will loop endlessly until loop state is changed or /// Track will loop endlessly until loop state is changed or
/// manually stopped. /// manually stopped.
@@ -11,7 +11,7 @@ pub enum LoopState {
/// ///
/// `Finite(0)` is the `Default`, stopping the track once its [`Input`] ends. /// `Finite(0)` is the `Default`, stopping the track once its [`Input`] ends.
/// ///
/// [`Input`]: ../input/struct.Input.html /// [`Input`]: crate::input::Input
Finite(usize), Finite(usize),
} }

View File

@@ -361,8 +361,8 @@ impl Track {
/// Typically, this would be used if you wished to directly work on or configure /// Typically, this would be used if you wished to directly work on or configure
/// the [`Track`] object before it is passed over to the driver. /// the [`Track`] object before it is passed over to the driver.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
/// [`TrackHandle`]: struct.TrackHandle.html /// [`TrackHandle`]: TrackHandle
pub fn create_player(source: Input) -> (Track, TrackHandle) { pub fn create_player(source: Input) -> (Track, TrackHandle) {
let (tx, rx) = mpsc::unbounded_channel(); let (tx, rx) = mpsc::unbounded_channel();
let can_seek = source.is_seekable(); let can_seek = source.is_seekable();
@@ -378,7 +378,7 @@ pub fn create_player(source: Input) -> (Track, TrackHandle) {
/// Failure indicates that the accessed audio object has been /// Failure indicates that the accessed audio object has been
/// removed or deleted by the audio context. /// removed or deleted by the audio context.
/// ///
/// [`TrackHandle`]: struct.TrackHandle.html /// [`TrackHandle`]: TrackHandle
pub type TrackResult = Result<(), SendError<TrackCommand>>; pub type TrackResult = Result<(), SendError<TrackCommand>>;
/// Alias for return value from calls to [`TrackHandle::get_info`]. /// Alias for return value from calls to [`TrackHandle::get_info`].
@@ -389,5 +389,5 @@ pub type TrackResult = Result<(), SendError<TrackCommand>>;
/// Failure indicates that the accessed audio object has been /// Failure indicates that the accessed audio object has been
/// removed or deleted by the audio context. /// removed or deleted by the audio context.
/// ///
/// [`TrackHandle::get_info`]: struct.TrackHandle.html#method.get_info /// [`TrackHandle::get_info`]: TrackHandle::get_info
pub type TrackQueryResult = Result<OneshotReceiver<Box<TrackState>>, SendError<TrackCommand>>; pub type TrackQueryResult = Result<OneshotReceiver<Box<TrackState>>, SendError<TrackCommand>>;

View File

@@ -1,5 +1,6 @@
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// Playback status of a track. /// Playback status of a track.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum PlayMode { pub enum PlayMode {
/// The track is currently playing. /// The track is currently playing.
Play, Play,

View File

@@ -53,8 +53,8 @@ use tracing::{info, warn};
/// # }; /// # };
/// ``` /// ```
/// ///
/// [`TrackEvent`]: ../events/enum.TrackEvent.html /// [`TrackEvent`]: crate::events::TrackEvent
/// [`Driver::queue`]: ../driver/struct.Driver.html#method.queue /// [`Driver::queue`]: crate::driver::Driver::queue
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct TrackQueue { pub struct TrackQueue {
// NOTE: the choice of a parking lot mutex is quite deliberate // NOTE: the choice of a parking lot mutex is quite deliberate
@@ -88,7 +88,7 @@ impl Queued {
/// This abstracts away thread-safety from the user, /// This abstracts away thread-safety from the user,
/// and offers a convenient location to store further state if required. /// and offers a convenient location to store further state if required.
/// ///
/// [`TrackQueue`]: struct.TrackQueue.html /// [`TrackQueue`]: TrackQueue
struct TrackQueueCore { struct TrackQueueCore {
tracks: VecDeque<Queued>, tracks: VecDeque<Queued>,
} }
@@ -163,11 +163,11 @@ impl TrackQueue {
/// Adds a [`Track`] object to the queue, to be played in the channel managed by `handler`. /// Adds a [`Track`] object to the queue, to be played in the channel managed by `handler`.
/// ///
/// This is used with [`voice::create_player`] if additional configuration or event handlers /// This is used with [`create_player`] if additional configuration or event handlers
/// are required before enqueueing the audio track. /// are required before enqueueing the audio track.
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
/// [`voice::create_player`]: fn.create_player.html /// [`create_player`]: super::create_player
pub fn add(&self, mut track: Track, handler: &mut Driver) { pub fn add(&self, mut track: Track, handler: &mut Driver) {
self.add_raw(&mut track); self.add_raw(&mut track);
handler.play(track); handler.play(track);
@@ -208,7 +208,7 @@ impl TrackQueue {
/// ///
/// The returned entry can be readded to *this* queue via [`modify_queue`]. /// The returned entry can be readded to *this* queue via [`modify_queue`].
/// ///
/// [`modify_queue`]: #method.modify_queue /// [`modify_queue`]: TrackQueue::modify_queue
pub fn dequeue(&self, index: usize) -> Option<Queued> { pub fn dequeue(&self, index: usize) -> Option<Queued> {
self.modify_queue(|vq| vq.remove(index)) self.modify_queue(|vq| vq.remove(index))
} }
@@ -285,7 +285,7 @@ impl TrackQueue {
/// ///
/// Use [`modify_queue`] for direct modification of the queue. /// Use [`modify_queue`] for direct modification of the queue.
/// ///
/// [`modify_queue`]: #method.modify_queue /// [`modify_queue`]: TrackQueue::modify_queue
pub fn current_queue(&self) -> Vec<TrackHandle> { pub fn current_queue(&self) -> Vec<TrackHandle> {
let inner = self.inner.lock(); let inner = self.inner.lock();

View File

@@ -1,12 +1,10 @@
use super::*; use super::*;
/// State of an [`Track`] object, designed to be passed to event handlers /// State of an [`Track`] object, designed to be passed to event handlers
/// and retrieved remotely via [`TrackHandle::get_info`] or /// and retrieved remotely via [`TrackHandle::get_info`].
/// [`TrackHandle::get_info_blocking`].
/// ///
/// [`Track`]: struct.Track.html /// [`Track`]: Track
/// [`TrackHandle::get_info`]: struct.TrackHandle.html#method.get_info /// [`TrackHandle::get_info`]: TrackHandle::get_info
/// [`TrackHandle::get_info_blocking`]: struct.TrackHandle.html#method.get_info_blocking
#[derive(Copy, Clone, Debug, Default, PartialEq)] #[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct TrackState { pub struct TrackState {
/// Play status (e.g., active, paused, stopped) of this track. /// Play status (e.g., active, paused, stopped) of this track.
@@ -15,7 +13,8 @@ pub struct TrackState {
pub volume: f32, pub volume: f32,
/// Current playback position in the source. /// Current playback position in the source.
/// ///
/// This is altered by loops and seeks /// This is altered by loops and seeks, and represents this track's
/// position in its underlying input stream.
pub position: Duration, pub position: Duration,
/// Total playback time, increasing monotonically. /// Total playback time, increasing monotonically.
pub play_time: Duration, pub play_time: Duration,