mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 01:39:28 +02:00

* connect: add shuffle_vec.rs * connect: shuffle in place * add shuffle with seed option * reduce complexity to add new metadata fields * add context index to metadata * use seed for shuffle When losing the connection and restarting the dealer, the seed is now stored in the context metadata. So on transfer we can pickup the seed again and shuffle the context as it was previously * add log for shuffle seed * connect: use small_rng, derive Default * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
82 lines
2.9 KiB
Rust
82 lines
2.9 KiB
Rust
use crate::{
|
|
protocol::{context::Context, context_track::ContextTrack, player::ProvidedTrack},
|
|
state::context::StateContext,
|
|
};
|
|
use std::collections::HashMap;
|
|
use std::fmt::Display;
|
|
|
|
const CONTEXT_URI: &str = "context_uri";
|
|
const ENTITY_URI: &str = "entity_uri";
|
|
const IS_QUEUED: &str = "is_queued";
|
|
const IS_AUTOPLAY: &str = "autoplay.is_autoplay";
|
|
const HIDDEN: &str = "hidden";
|
|
const ITERATION: &str = "iteration";
|
|
|
|
const CUSTOM_CONTEXT_INDEX: &str = "context_index";
|
|
const CUSTOM_SHUFFLE_SEED: &str = "shuffle_seed";
|
|
|
|
macro_rules! metadata_entry {
|
|
( $get:ident, $set:ident, $clear:ident ($key:ident: $entry:ident)) => {
|
|
metadata_entry!( $get use get, $set, $clear ($key: $entry) -> Option<&String> );
|
|
};
|
|
( $get_key:ident use $get:ident, $set:ident, $clear:ident ($key:ident: $entry:ident) -> $ty:ty ) => {
|
|
fn $get_key (&self) -> $ty {
|
|
self.$get($entry)
|
|
}
|
|
|
|
fn $set (&mut self, $key: impl Display) {
|
|
self.metadata_mut().insert($entry.to_string(), $key.to_string());
|
|
}
|
|
|
|
fn $clear(&mut self) {
|
|
self.metadata_mut().remove($entry);
|
|
}
|
|
};
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub trait Metadata {
|
|
fn metadata(&self) -> &HashMap<String, String>;
|
|
fn metadata_mut(&mut self) -> &mut HashMap<String, String>;
|
|
|
|
fn get_bool(&self, entry: &str) -> bool {
|
|
matches!(self.metadata().get(entry), Some(entry) if entry.eq("true"))
|
|
}
|
|
|
|
fn get_usize(&self, entry: &str) -> Option<usize> {
|
|
self.metadata().get(entry)?.parse().ok()
|
|
}
|
|
|
|
fn get(&self, entry: &str) -> Option<&String> {
|
|
self.metadata().get(entry)
|
|
}
|
|
|
|
metadata_entry!(is_from_queue use get_bool, set_from_queue, remove_from_queue (is_queued: IS_QUEUED) -> bool);
|
|
metadata_entry!(is_from_autoplay use get_bool, set_from_autoplay, remove_from_autoplay (is_autoplay: IS_AUTOPLAY) -> bool);
|
|
metadata_entry!(is_hidden use get_bool, set_hidden, remove_hidden (is_hidden: HIDDEN) -> bool);
|
|
|
|
metadata_entry!(get_context_index use get_usize, set_context_index, remove_context_index (context_index: CUSTOM_CONTEXT_INDEX) -> Option<usize>);
|
|
metadata_entry!(get_context_uri, set_context_uri, remove_context_uri (context_uri: CONTEXT_URI));
|
|
metadata_entry!(get_entity_uri, set_entity_uri, remove_entity_uri (entity_uri: ENTITY_URI));
|
|
metadata_entry!(get_iteration, set_iteration, remove_iteration (iteration: ITERATION));
|
|
metadata_entry!(get_shuffle_seed, set_shuffle_seed, remove_shuffle_seed (shuffle_seed: CUSTOM_SHUFFLE_SEED));
|
|
}
|
|
|
|
macro_rules! impl_metadata {
|
|
($impl_for:ident) => {
|
|
impl Metadata for $impl_for {
|
|
fn metadata(&self) -> &HashMap<String, String> {
|
|
&self.metadata
|
|
}
|
|
|
|
fn metadata_mut(&mut self) -> &mut HashMap<String, String> {
|
|
&mut self.metadata
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_metadata!(ContextTrack);
|
|
impl_metadata!(ProvidedTrack);
|
|
impl_metadata!(Context);
|
|
impl_metadata!(StateContext);
|