Skip to content

More chrono::Duration usage in the API #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.11.7 (Unreleased)

- ([#375](https://github.com/ramsayleung/rspotify/pull/375)) We now use `chrono::Duration` in more places for consistency and usability: `start_uris_playback`, `start_context_playback`, `rspotify_model::Offset`, `resume_playback`, `seek_track`. Some of these fields have been renamed from `position_ms` to `position`.

## 0.11.6 (2022.12.14)

- ([#331](https://github.com/ramsayleung/rspotify/pull/331)) `Market` is now `Copy`
Expand Down
2 changes: 1 addition & 1 deletion examples/ureq/seek_track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
// This function requires the `cli` feature enabled.
spotify.prompt_for_token(&url).unwrap();

match spotify.seek_track(25000, None) {
match spotify.seek_track(chrono::Duration::seconds(25), None) {
Ok(_) => println!("Change to previous playback successful"),
Err(_) => eprintln!("Change to previous playback failed"),
}
Expand Down
4 changes: 3 additions & 1 deletion rspotify-model/src/offset.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Offset object

use chrono::Duration;

/// Offset object
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Offset {
Position(u32),
Position(Duration),
Uri(String),
}
46 changes: 27 additions & 19 deletions src/clients/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
ClientResult, OAuth, Token,
};

use std::{collections::HashMap, time};
use std::collections::HashMap;

use maybe_async::maybe_async;
use rspotify_model::idtypes::{PlayContextId, PlayableId};
Expand Down Expand Up @@ -301,12 +301,12 @@ pub trait OAuthClient: BaseClient {
&self,
playlist_id: PlaylistId<'_>,
items: impl IntoIterator<Item = PlayableId<'a>> + Send + 'a,
position: Option<i32>,
position: Option<chrono::Duration>,
) -> ClientResult<PlaylistResult> {
let uris = items.into_iter().map(|id| id.uri()).collect::<Vec<_>>();
let params = JsonBuilder::new()
.required("uris", uris)
.optional("position", position)
.optional("position", position.map(|p| p.num_milliseconds()))
.build();

let url = format!("playlists/{}/tracks", playlist_id.id());
Expand Down Expand Up @@ -752,8 +752,8 @@ pub trait OAuthClient: BaseClient {
///
/// Parameters:
/// - limit - the number of entities to return
/// - time_limit - a Unix timestamp in milliseconds. Returns all items after
/// or before (but not including) this cursor position.
/// - time_limit - a timestamp. The endpoint will return all items after
/// or before (but not including) this cursor position.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/get-recently-played)
async fn current_user_recently_played(
Expand Down Expand Up @@ -1029,26 +1029,28 @@ pub trait OAuthClient: BaseClient {
/// - context_uri - spotify context uri to play
/// - uris - spotify track uris
/// - offset - offset into context by index or track
/// - position_ms - Indicates from what position to start playback.
/// - position - Indicates from what position to start playback.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/start-a-users-playback)
async fn start_context_playback(
&self,
context_uri: PlayContextId<'_>,
device_id: Option<&str>,
offset: Option<Offset>,
position_ms: Option<time::Duration>,
position: Option<chrono::Duration>,
) -> ClientResult<()> {
let params = JsonBuilder::new()
.required("context_uri", context_uri.uri())
.optional(
"offset",
offset.map(|x| match x {
Offset::Position(position) => json!({ "position": position }),
Offset::Position(position) => {
json!({ "position": position.num_milliseconds() })
}
Offset::Uri(uri) => json!({ "uri": uri }),
}),
)
.optional("position_ms", position_ms)
.optional("position_ms", position.map(|p| p.num_milliseconds()))
.build();

let url = append_device_id("me/player/play", device_id);
Expand All @@ -1063,26 +1065,28 @@ pub trait OAuthClient: BaseClient {
/// - uris
/// - device_id
/// - offset
/// - position_ms
/// - position
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/start-a-users-playback)
async fn start_uris_playback<'a>(
&self,
uris: impl IntoIterator<Item = PlayableId<'a>> + Send + 'a,
device_id: Option<&str>,
offset: Option<crate::model::Offset>,
position_ms: Option<u32>,
position: Option<chrono::Duration>,
) -> ClientResult<()> {
let params = JsonBuilder::new()
.required(
"uris",
uris.into_iter().map(|id| id.uri()).collect::<Vec<_>>(),
)
.optional("position_ms", position_ms)
.optional("position_ms", position.map(|p| p.num_milliseconds()))
.optional(
"offset",
offset.map(|x| match x {
Offset::Position(position) => json!({ "position": position }),
Offset::Position(position) => {
json!({ "position": position.num_milliseconds() })
}
Offset::Uri(uri) => json!({ "uri": uri }),
}),
)
Expand Down Expand Up @@ -1111,16 +1115,16 @@ pub trait OAuthClient: BaseClient {
///
/// Parameters:
/// - device_id - device target for playback
/// - position_ms
/// - position
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/start-a-users-playback)
async fn resume_playback(
&self,
device_id: Option<&str>,
position_ms: Option<u32>,
position: Option<chrono::Duration>,
) -> ClientResult<()> {
let params = JsonBuilder::new()
.optional("position_ms", position_ms)
.optional("position_ms", position.map(|p| p.num_milliseconds()))
.build();

let url = append_device_id("me/player/play", device_id);
Expand Down Expand Up @@ -1158,13 +1162,17 @@ pub trait OAuthClient: BaseClient {
/// Seek To Position In Currently Playing Track.
///
/// Parameters:
/// - position_ms - position in milliseconds to seek to
/// - position - position in milliseconds to seek to
/// - device_id - device target for playback
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/seek-to-position-in-currently-playing-track)
async fn seek_track(&self, position_ms: u32, device_id: Option<&str>) -> ClientResult<()> {
async fn seek_track(
&self,
position: chrono::Duration,
device_id: Option<&str>,
) -> ClientResult<()> {
let url = append_device_id(
&format!("me/player/seek?position_ms={position_ms}"),
&format!("me/player/seek?position_ms={}", position.num_milliseconds()),
device_id,
);
self.endpoint_put(&url, &json!({})).await?;
Expand Down
14 changes: 7 additions & 7 deletions tests/test_with_oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ async fn test_playback() {
.start_uris_playback(
uris.iter().map(PlayableId::as_ref),
Some(device_id),
Some(Offset::Position(0)),
Some(Offset::Position(chrono::Duration::zero())),
None,
)
.await
Expand Down Expand Up @@ -389,7 +389,7 @@ async fn test_playback() {
if let Some(uri) = uri {
let offset = None;
let device = backup.device.id.as_deref();
let position = backup.progress.map(|p| p.num_milliseconds() as u32);
let position = backup.progress;
client
.start_uris_playback(uri, device, offset, position)
.await
Expand Down Expand Up @@ -527,17 +527,17 @@ async fn test_seek_track() {
// Saving the previous state to restore it later
let backup = client.current_playback(None, None::<&[_]>).await.unwrap();

client.seek_track(25000, None).await.unwrap();
client
.seek_track(chrono::Duration::seconds(25), None)
.await
.unwrap();

if let Some(CurrentPlaybackContext {
progress: Some(progress),
..
}) = backup
{
client
.seek_track(progress.num_milliseconds() as u32, None)
.await
.unwrap();
client.seek_track(progress, None).await.unwrap();
}
}

Expand Down