Skip to content

Commit 75729ba

Browse files
committed
refactor: Introduce SpotifyUri struct
Contributes to #1266 Introduces a new `SpotifyUri` struct which is layered on top of the existing `SpotifyId`, but has the capability to support URIs that do not confirm to the canonical base62 encoded format. This allows it to describe URIs like `spotify:local`, `spotify:genre` and others that `SpotifyId` cannot represent. Changed the internal player state to use these URIs as much as possible, such that the player could in the future accept a URI of the type `spotify:local`, as a means of laying the groundwork for local file support.
1 parent 882ed7c commit 75729ba

File tree

23 files changed

+1027
-628
lines changed

23 files changed

+1027
-628
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- [playback] Add `load_uri()` function to load a `SpotifyUri`
13+
- [playback] Add `preload_uri()` function to load a `SpotifyUri`
14+
- [core] Add `SpotifyUri` type to represent more types of URI than `SpotifyId` can
15+
1216
### Changed
1317

18+
- [connect] Changed `track_id` parameter in `SpircTask::handle_unavailable` from `SpotifyId` to `&SpotifyUri` (breaking)
19+
- [connect] Changed return type of `ConnectState::preview_next_track` from `Option<SpotifyId>` to
20+
`Option<SpotifyUri>` (breaking)
21+
- [connect] Changed type of `id` parameter `ConnectState::mark_unavailable` from `SpotifyId` to `&SpotifyUri` (breaking)
22+
- [playback] Changed type of `SpotifyId` fields in `PlayerEvent` members to `SpotifyUri` (breaking)
23+
- [metadata] Changed arguments for `Metadata` trait from `&SpotifyId` to `&SpotifyUri` (breaking)
24+
1425
### Deprecated
1526

27+
- [player] `load()` function marked for deprecation
28+
- [player] `preload()` function marked for deprecation
29+
1630
### Removed
1731

1832
### Fixed

connect/src/spirc.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
LoadContextOptions, LoadRequestOptions, PlayContext,
33
context_resolver::{ContextAction, ContextResolver, ResolveContext},
44
core::{
5-
Error, Session, SpotifyId,
5+
Error, Session, SpotifyUri,
66
authentication::Credentials,
77
dealer::{
88
manager::{BoxedStream, BoxedStreamResult, Reply, RequestReply},
@@ -778,7 +778,7 @@ impl SpircTask {
778778
return Ok(());
779779
}
780780
PlayerEvent::Unavailable { track_id, .. } => {
781-
self.handle_unavailable(track_id)?;
781+
self.handle_unavailable(&track_id)?;
782782
if self.connect_state.current_track(|t| &t.uri) == &track_id.to_uri()? {
783783
self.handle_next(None)?
784784
}
@@ -1494,12 +1494,12 @@ impl SpircTask {
14941494
}
14951495

14961496
if let Some(track_id) = self.connect_state.preview_next_track() {
1497-
self.player.preload(track_id);
1497+
self.player.preload_uri(track_id);
14981498
}
14991499
}
15001500

15011501
// Mark unavailable tracks so we can skip them later
1502-
fn handle_unavailable(&mut self, track_id: SpotifyId) -> Result<(), Error> {
1502+
fn handle_unavailable(&mut self, track_id: &SpotifyUri) -> Result<(), Error> {
15031503
self.connect_state.mark_unavailable(track_id)?;
15041504
self.handle_preload_next_track();
15051505

@@ -1704,8 +1704,8 @@ impl SpircTask {
17041704
}
17051705

17061706
let current_uri = self.connect_state.current_track(|t| &t.uri);
1707-
let id = SpotifyId::from_uri(current_uri)?;
1708-
self.player.load(id, start_playing, position_ms);
1707+
let id = SpotifyUri::from_uri(current_uri)?;
1708+
self.player.load_uri(id, start_playing, position_ms);
17091709

17101710
self.connect_state
17111711
.update_position(position_ms, self.now_ms());

connect/src/state/context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
core::{Error, SpotifyId},
2+
core::{Error, SpotifyUri},
33
protocol::{
44
context::Context,
55
context_page::ContextPage,
@@ -14,6 +14,7 @@ use crate::{
1414
provider::{IsProvider, Provider},
1515
},
1616
};
17+
use librespot_core::spotify_id::SpotifyItemType;
1718
use protobuf::MessageField;
1819
use std::collections::HashMap;
1920
use uuid::Uuid;
@@ -444,8 +445,8 @@ impl ConnectState {
444445
(Some(uri), _) if uri.contains(['?', '%']) => {
445446
Err(StateError::InvalidTrackUri(Some(uri.clone())))?
446447
}
447-
(Some(uri), _) if !uri.is_empty() => SpotifyId::from_uri(uri)?,
448-
(_, Some(gid)) if !gid.is_empty() => SpotifyId::from_raw(gid)?,
448+
(Some(uri), _) if !uri.is_empty() => SpotifyUri::from_uri(uri)?,
449+
(_, Some(gid)) if !gid.is_empty() => SpotifyUri::from_raw(gid, SpotifyItemType::Track)?,
449450
_ => Err(StateError::InvalidTrackUri(None))?,
450451
};
451452

connect/src/state/tracks.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
core::{Error, SpotifyId},
2+
core::{Error, SpotifyUri},
33
protocol::player::ProvidedTrack,
44
state::{
55
ConnectState, SPOTIFY_MAX_NEXT_TRACKS_SIZE, SPOTIFY_MAX_PREV_TRACKS_SIZE, StateError,
@@ -348,14 +348,14 @@ impl<'ct> ConnectState {
348348
Ok(())
349349
}
350350

351-
pub fn preview_next_track(&mut self) -> Option<SpotifyId> {
351+
pub fn preview_next_track(&mut self) -> Option<SpotifyUri> {
352352
let next = if self.repeat_track() {
353353
self.current_track(|t| &t.uri)
354354
} else {
355355
&self.next_tracks().first()?.uri
356356
};
357357

358-
SpotifyId::from_uri(next).ok()
358+
SpotifyUri::from_uri(next).ok()
359359
}
360360

361361
pub fn has_next_tracks(&self, min: Option<usize>) -> bool {
@@ -377,7 +377,7 @@ impl<'ct> ConnectState {
377377
prev
378378
}
379379

380-
pub fn mark_unavailable(&mut self, id: SpotifyId) -> Result<(), Error> {
380+
pub fn mark_unavailable(&mut self, id: &SpotifyUri) -> Result<(), Error> {
381381
let uri = id.to_uri()?;
382382

383383
debug!("marking {uri} as unavailable");

core/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ mod socket;
3232
#[allow(dead_code)]
3333
pub mod spclient;
3434
pub mod spotify_id;
35+
pub mod spotify_uri;
3536
pub mod token;
3637
#[doc(hidden)]
3738
pub mod util;
@@ -42,3 +43,4 @@ pub use error::Error;
4243
pub use file_id::FileId;
4344
pub use session::Session;
4445
pub use spotify_id::SpotifyId;
46+
pub use spotify_uri::SpotifyUri;

core/src/spclient.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55

66
use crate::config::{OS, os_version};
77
use crate::{
8-
Error, FileId, SpotifyId,
8+
Error, FileId, SpotifyId, SpotifyUri,
99
apresolve::SocketAddress,
1010
config::SessionConfig,
1111
error::ErrorKind,
@@ -676,10 +676,10 @@ impl SpClient {
676676
.await
677677
}
678678

679-
pub async fn get_radio_for_track(&self, track_id: &SpotifyId) -> SpClientResult {
679+
pub async fn get_radio_for_track(&self, track_uri: &SpotifyUri) -> SpClientResult {
680680
let endpoint = format!(
681681
"/inspiredby-mix/v2/seed_to_playlist/{}?response-format=json",
682-
track_id.to_uri()?
682+
track_uri.to_uri()?
683683
);
684684

685685
self.request_as_json(&Method::GET, &endpoint, None, None)

0 commit comments

Comments
 (0)