Parse named ID URIs

This commit is contained in:
George Hahn 2023-01-02 16:24:49 -07:00
parent edf646d4bb
commit 7a259ccc4b
2 changed files with 30 additions and 3 deletions

View file

@ -85,6 +85,7 @@ https://github.com/librespot-org/librespot
downloads even if librespot doesn't use that for playback itself. downloads even if librespot doesn't use that for playback itself.
- [core] Support downloading of lyrics - [core] Support downloading of lyrics
- [core] Support parsing `SpotifyId` for local files - [core] Support parsing `SpotifyId` for local files
- [core] Support parsing `SpotifyId` for named playlists
- [main] Add all player events to `player_event_handler.rs` - [main] Add all player events to `player_event_handler.rs`
- [main] Add an event worker thread that runs async to the main thread(s) but - [main] Add an event worker thread that runs async to the main thread(s) but
sync to itself to prevent potential data races for event consumers sync to itself to prevent potential data races for event consumers

View file

@ -170,9 +170,24 @@ impl SpotifyId {
/// ///
/// [Spotify URI]: https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids /// [Spotify URI]: https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids
pub fn from_uri(src: &str) -> SpotifyIdResult { pub fn from_uri(src: &str) -> SpotifyIdResult {
// At minimum, should be `spotify:{type}:{id}` // Basic: `spotify:{type}:{id}`
let (scheme, tail) = src.split_once(':').ok_or(SpotifyIdError::InvalidFormat)?; // Named: `spotify:user:{user}:{type}:{id}`
let (item_type, id) = tail.split_once(':').ok_or(SpotifyIdError::InvalidFormat)?; // Local: `spotify:local:{artist}:{album_title}:{track_title}:{duration_in_seconds}`
let mut parts = src.split(':');
let scheme = parts.next().ok_or(SpotifyIdError::InvalidFormat)?;
let item_type = {
let next = parts.next().ok_or(SpotifyIdError::InvalidFormat)?;
if next == "user" {
let _username = parts.next().ok_or(SpotifyIdError::InvalidFormat)?;
parts.next().ok_or(SpotifyIdError::InvalidFormat)?
} else {
next
}
};
let id = parts.next().ok_or(SpotifyIdError::InvalidFormat)?;
if scheme != "spotify" { if scheme != "spotify" {
return Err(SpotifyIdError::InvalidRoot.into()); return Err(SpotifyIdError::InvalidRoot.into());
@ -701,6 +716,17 @@ mod tests {
assert_eq!(actual.item_type, SpotifyItemType::Local); assert_eq!(actual.item_type, SpotifyItemType::Local);
} }
#[test]
fn from_named_uri() {
let actual =
NamedSpotifyId::from_uri("spotify:user:spotify:playlist:37i9dQZF1DWSw8liJZcPOI")
.unwrap();
assert_eq!(actual.id, 136159921382084734723401526672209703396);
assert_eq!(actual.item_type, SpotifyItemType::Playlist);
assert_eq!(actual.username, "spotify");
}
#[test] #[test]
fn to_uri() { fn to_uri() {
for c in &CONV_VALID { for c in &CONV_VALID {