use std::sync::Mutex;
use tf_observer::{Observable, Observer, ObserverList};
pub struct Playlist<T> {
observers: ObserverList<PlaylistEvent<T>>,
playlist: Vec<T>,
}
impl<T> Playlist<T>
where
T: Eq + Clone,
{
pub fn new() -> Self {
Self {
observers: ObserverList::new(),
playlist: Vec::new(),
}
}
pub fn toggle(&mut self, item: &T) {
if let Some(_i) = self.playlist.iter().find(|&i| i == item) {
log::debug!("Removing item from playlist");
self.playlist.retain(|i| i != item);
self.observers.notify(PlaylistEvent::Remove(item.clone()))
} else {
log::debug!("Adding item to playlist");
self.playlist.push(item.clone());
self.observers.notify(PlaylistEvent::Add(item.clone()))
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.playlist.iter()
}
pub fn len(&self) -> usize {
self.playlist.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, item: &T) -> Option<&T> {
self.playlist.iter().find(|&i| i == item)
}
}
impl<T> Default for Playlist<T>
where
T: Eq + Clone,
{
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub enum PlaylistEvent<T> {
Add(T),
Remove(T),
}
impl<T> Observable<PlaylistEvent<T>> for Playlist<T>
where
T: Clone,
{
fn attach(
&mut self,
observer: std::sync::Weak<Mutex<Box<(dyn Observer<PlaylistEvent<T>> + Send + 'static)>>>,
) {
self.observers.attach(observer);
}
fn detach(
&mut self,
observer: std::sync::Weak<Mutex<Box<(dyn Observer<PlaylistEvent<T>> + Send + 'static)>>>,
) {
self.observers.detach(observer);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn playlist_toggle() {
let mut playlist: Playlist<&str> = Playlist::new();
assert_eq!(playlist.len(), 0);
playlist.toggle(&"Item1");
assert_eq!(playlist.len(), 1);
playlist.toggle(&"Item2");
assert_eq!(playlist.len(), 2);
playlist.toggle(&"Item2");
assert_eq!(playlist.len(), 1);
}
}