connect: move ResolveContext in own file

This commit is contained in:
Felix Prillwitz 2024-12-11 17:36:33 +01:00
parent c73871c516
commit d2f1dee43c
No known key found for this signature in database
GPG key ID: DE334B43606D1455
4 changed files with 101 additions and 97 deletions

View file

@ -0,0 +1,91 @@
use crate::state::ConnectState;
use librespot_protocol::player::Context;
use std::{
fmt::{Display, Formatter},
hash::{Hash, Hasher},
};
#[derive(Debug, Clone)]
pub(super) struct ResolveContext {
context: Context,
fallback: Option<String>,
autoplay: bool,
}
impl ResolveContext {
pub fn from_uri(uri: impl Into<String>, fallback: impl Into<String>, autoplay: bool) -> Self {
let fallback_uri = fallback.into();
Self {
context: Context {
uri: uri.into(),
..Default::default()
},
fallback: (!fallback_uri.is_empty()).then_some(fallback_uri),
autoplay,
}
}
pub fn from_context(context: Context, autoplay: bool) -> Self {
Self {
context,
fallback: None,
autoplay,
}
}
/// the uri which should be used to resolve the context, might not be the context uri
pub fn resolve_uri(&self) -> Option<&String> {
// it's important to call this always, or at least for every ResolveContext
// otherwise we might not even check if we need to fallback and just use the fallback uri
ConnectState::get_context_uri_from_context(&self.context)
.and_then(|s| (!s.is_empty()).then_some(s))
.or(self.fallback.as_ref())
}
/// the actual context uri
pub fn context_uri(&self) -> &str {
&self.context.uri
}
pub fn autoplay(&self) -> bool {
self.autoplay
}
}
impl Display for ResolveContext {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"resolve_uri: <{:?}>, context_uri: <{}>, autoplay: <{}>",
self.resolve_uri(),
self.context.uri,
self.autoplay,
)
}
}
impl PartialEq for ResolveContext {
fn eq(&self, other: &Self) -> bool {
let eq_context = self.context_uri() == other.context_uri();
let eq_resolve = self.resolve_uri() == other.resolve_uri();
let eq_autoplay = self.autoplay == other.autoplay;
eq_context && eq_resolve && eq_autoplay
}
}
impl Eq for ResolveContext {}
impl Hash for ResolveContext {
fn hash<H: Hasher>(&self, state: &mut H) {
self.context_uri().hash(state);
self.resolve_uri().hash(state);
self.autoplay.hash(state);
}
}
impl From<ResolveContext> for Context {
fn from(value: ResolveContext) -> Self {
value.context
}
}

View file

@ -5,6 +5,7 @@ use librespot_core as core;
use librespot_playback as playback; use librespot_playback as playback;
use librespot_protocol as protocol; use librespot_protocol as protocol;
mod context_resolver;
mod model; mod model;
pub mod spirc; pub mod spirc;
pub mod state; pub mod state;

View file

@ -1,8 +1,4 @@
use crate::state::ConnectState;
use librespot_core::dealer::protocol::SkipTo; use librespot_core::dealer::protocol::SkipTo;
use librespot_protocol::player::Context;
use std::fmt::{Display, Formatter};
use std::hash::{Hash, Hasher};
#[derive(Debug)] #[derive(Debug)]
pub struct SpircLoadCommand { pub struct SpircLoadCommand {
@ -58,88 +54,3 @@ pub(super) enum SpircPlayStatus {
preloading_of_next_track_triggered: bool, preloading_of_next_track_triggered: bool,
}, },
} }
#[derive(Debug, Clone)]
pub(super) struct ResolveContext {
context: Context,
fallback: Option<String>,
autoplay: bool,
}
impl ResolveContext {
pub fn from_uri(uri: impl Into<String>, fallback: impl Into<String>, autoplay: bool) -> Self {
let fallback_uri = fallback.into();
Self {
context: Context {
uri: uri.into(),
..Default::default()
},
fallback: (!fallback_uri.is_empty()).then_some(fallback_uri),
autoplay,
}
}
pub fn from_context(context: Context, autoplay: bool) -> Self {
Self {
context,
fallback: None,
autoplay,
}
}
/// the uri which should be used to resolve the context, might not be the context uri
pub fn resolve_uri(&self) -> Option<&String> {
// it's important to call this always, or at least for every ResolveContext
// otherwise we might not even check if we need to fallback and just use the fallback uri
ConnectState::get_context_uri_from_context(&self.context)
.and_then(|s| (!s.is_empty()).then_some(s))
.or(self.fallback.as_ref())
}
/// the actual context uri
pub fn context_uri(&self) -> &str {
&self.context.uri
}
pub fn autoplay(&self) -> bool {
self.autoplay
}
}
impl Display for ResolveContext {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"resolve_uri: <{:?}>, context_uri: <{}>, autoplay: <{}>",
self.resolve_uri(),
self.context.uri,
self.autoplay,
)
}
}
impl PartialEq for ResolveContext {
fn eq(&self, other: &Self) -> bool {
let eq_context = self.context_uri() == other.context_uri();
let eq_resolve = self.resolve_uri() == other.resolve_uri();
let eq_autoplay = self.autoplay == other.autoplay;
eq_context && eq_resolve && eq_autoplay
}
}
impl Eq for ResolveContext {}
impl Hash for ResolveContext {
fn hash<H: Hasher>(&self, state: &mut H) {
self.context_uri().hash(state);
self.resolve_uri().hash(state);
self.autoplay.hash(state);
}
}
impl From<ResolveContext> for Context {
fn from(value: ResolveContext) -> Self {
value.context
}
}

View file

@ -1,5 +1,14 @@
pub use crate::model::{PlayingTrack, SpircLoadCommand}; pub use crate::model::{PlayingTrack, SpircLoadCommand};
use crate::state::{context::ResetContext, metadata::Metadata}; use crate::state::{context::ResetContext, metadata::Metadata};
use crate::{
context_resolver::ResolveContext,
model::SpircPlayStatus,
state::{
context::{ContextType, UpdateContext},
provider::IsProvider,
{ConnectState, ConnectStateConfig},
},
};
use crate::{ use crate::{
core::{ core::{
authentication::Credentials, authentication::Credentials,
@ -24,14 +33,6 @@ use crate::{
user_attributes::UserAttributesMutation, user_attributes::UserAttributesMutation,
}, },
}; };
use crate::{
model::{ResolveContext, SpircPlayStatus},
state::{
context::{ContextType, UpdateContext},
provider::IsProvider,
{ConnectState, ConnectStateConfig},
},
};
use futures_util::StreamExt; use futures_util::StreamExt;
use protobuf::MessageField; use protobuf::MessageField;
use std::collections::HashMap; use std::collections::HashMap;