dj-kitty-cat/src/queue.rs
2023-03-07 20:53:54 -05:00

102 lines
2.5 KiB
Rust

//! Implements a queue for the bot to play songs in order
use anyhow::Result;
use songbird::{
input::Input,
tracks::{self, TrackHandle},
Driver,
};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum QueueError {
#[error("Nothing is in the queue.")]
EmptyQueue,
}
pub struct Queue {
queue: Vec<TrackHandle>,
}
impl Queue {
#[must_use]
pub fn new() -> Self {
Self { queue: Vec::new() }
}
/// Resumes the current track
pub fn resume(&mut self) -> Result<()> {
let Some(track) = self.queue.first() else {
return Err(QueueError::EmptyQueue.into());
};
track.play()?;
Ok(())
}
/// Stops the current track and removes it from the queue
pub fn stop(&mut self) -> Result<()> {
let Some(track) = self.queue.first() else {
return Err(QueueError::EmptyQueue.into());
};
track.stop()?;
self.queue.remove(0);
Ok(())
}
/// Pauses the current track
pub fn pause(&mut self) -> Result<()> {
let Some(track) = self.queue.first() else {
return Err(QueueError::EmptyQueue.into());
};
track.pause()?;
Ok(())
}
/// Adds a track to the end of the queue
pub fn add_to_end(&mut self, source: Input, handler: &mut Driver) -> TrackHandle {
let (mut track, handle) = tracks::create_player(source);
track.pause();
self.queue.push(handle.clone());
handler.play(track);
handle
}
/// Adds multiple tracks to the end of the queue
pub fn add_all_to_end(
&mut self,
sources: Vec<Input>,
handler: &mut Driver,
) -> Vec<TrackHandle> {
let mut handles = Vec::new();
for source in sources {
handles.push(self.add_to_end(source, handler));
}
handles
}
/// Adds a track to play next
pub fn add_next(&mut self, source: Input, handler: &mut Driver) -> TrackHandle {
let (mut track, handle) = tracks::create_player(source);
track.pause();
if self.queue.is_empty() {
self.queue.push(handle.clone());
} else {
self.queue.insert(1, handle.clone());
}
handler.play(track);
handle
}
/// Clears the queue
pub fn clear(&mut self) {
for track in self.queue.drain(..) {
let _ = track.stop();
}
}
/// Returns whether the queue is empty
#[must_use]
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
}