From 518e622ae06c5e4e5be0cf0cddfdb0bbff08063d Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Sun, 19 Sep 2021 20:33:34 +0200 Subject: [PATCH 1/9] Attempt two at conflict fixing --- Cargo.toml | 52 +++--------- examples/auth_code.rs | 2 +- examples/auth_code_pkce.rs | 2 +- examples/client_creds.rs | 2 +- examples/oauth_tokens.rs | 2 +- examples/pagination_async.rs | 2 +- examples/pagination_manual.rs | 2 +- examples/with_refresh_token.rs | 2 +- rspotify-sync/.env | 1 + rspotify-sync/Cargo.toml | 84 +++++++++++++++++++ .../ureq => rspotify-sync/examples}/device.rs | 2 +- .../ureq => rspotify-sync/examples}/me.rs | 2 +- .../examples}/pagination_sync.rs | 2 +- .../ureq => rspotify-sync/examples}/search.rs | 2 +- .../examples}/seek_track.rs | 2 +- 15 files changed, 109 insertions(+), 52 deletions(-) create mode 120000 rspotify-sync/.env create mode 100644 rspotify-sync/Cargo.toml rename {examples/ureq => rspotify-sync/examples}/device.rs (86%) rename {examples/ureq => rspotify-sync/examples}/me.rs (85%) rename {examples => rspotify-sync/examples}/pagination_sync.rs (92%) rename {examples/ureq => rspotify-sync/examples}/search.rs (99%) rename {examples/ureq => rspotify-sync/examples}/seek_track.rs (88%) diff --git a/Cargo.toml b/Cargo.toml index 8791824c..4b9ad7c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,11 +3,11 @@ authors = [ "Ramsay Leung ", "Mario Ortiz Manero " ] -name = "rspotify" +name = "rspotify-async" version = "0.10.0" license = "MIT" readme = "README.md" -description = "Spotify API wrapper" +description = "Asynchronous Spotify API wrapper" homepage = "https://github.com/ramsayleung/rspotify" repository = "https://github.com/ramsayleung/rspotify" keywords = ["spotify", "api"] @@ -20,6 +20,7 @@ members = [ "rspotify-http" ] exclude = [ + "rspotify-sync", "examples/webapp" ] # For advanced features usage in the CLI, see: @@ -59,9 +60,7 @@ cli = ["webbrowser"] env-file = ["dotenv"] ### HTTP ### -# Available clients. By default they don't include a TLS so that it can be -# configured. -client-ureq = ["rspotify-http/client-ureq", "__sync"] +# Only asynchronous clients are listed here. client-reqwest = ["rspotify-http/client-reqwest", "__async"] # Passing the TLS features to reqwest. @@ -69,12 +68,10 @@ reqwest-default-tls = ["rspotify-http/reqwest-default-tls"] reqwest-rustls-tls = ["rspotify-http/reqwest-rustls-tls"] reqwest-native-tls = ["rspotify-http/reqwest-native-tls"] reqwest-native-tls-vendored = ["rspotify-http/reqwest-native-tls-vendored"] -# Same for ureq. -ureq-rustls-tls = ["rspotify-http/ureq-rustls-tls"] # Internal features for checking async or sync compilation __async = ["futures", "async-stream", "async-trait"] -__sync = ["maybe-async/is_sync"] +__sync = [] [package.metadata.docs.rs] # Documenting the CLI methods, and working links for `dotenv` @@ -82,60 +79,35 @@ features = ["cli", "env-file"] [[example]] name = "client_creds" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/client_creds.rs" [[example]] name = "auth_code" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/auth_code.rs" [[example]] name = "auth_code_pkce" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/auth_code_pkce.rs" [[example]] name = "oauth_tokens" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/oauth_tokens.rs" [[example]] name = "with_refresh_token" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/with_refresh_token.rs" -[[example]] -name = "device" -required-features = ["env-file", "cli", "client-ureq"] -path = "examples/ureq/device.rs" - -[[example]] -name = "me" -required-features = ["env-file", "cli", "client-ureq"] -path = "examples/ureq/me.rs" - -[[example]] -name = "search" -required-features = ["env-file", "cli", "client-ureq"] -path = "examples/ureq/search.rs" - -[[example]] -name = "seek_track" -required-features = ["env-file", "cli", "client-ureq"] -path = "examples/ureq/seek_track.rs" - [[example]] name = "pagination_manual" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/pagination_manual.rs" -[[example]] -name = "pagination_sync" -required-features = ["env-file", "cli", "client-ureq"] -path = "examples/pagination_sync.rs" - [[example]] name = "pagination_async" -required-features = ["env-file", "cli", "client-reqwest"] +required-features = ["env-file", "cli"] path = "examples/pagination_async.rs" diff --git a/examples/auth_code.rs b/examples/auth_code.rs index 64796f99..01a51b8c 100644 --- a/examples/auth_code.rs +++ b/examples/auth_code.rs @@ -1,4 +1,4 @@ -use rspotify::{ +use rspotify_async::{ model::{AdditionalType, Country, Market}, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, diff --git a/examples/auth_code_pkce.rs b/examples/auth_code_pkce.rs index 5a35e4a6..0f4add50 100644 --- a/examples/auth_code_pkce.rs +++ b/examples/auth_code_pkce.rs @@ -1,4 +1,4 @@ -use rspotify::{prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth}; #[tokio::main] async fn main() { diff --git a/examples/client_creds.rs b/examples/client_creds.rs index edc9b4b5..8febb1e5 100644 --- a/examples/client_creds.rs +++ b/examples/client_creds.rs @@ -1,4 +1,4 @@ -use rspotify::{model::AlbumId, prelude::*, ClientCredsSpotify, Credentials}; +use rspotify_async::{model::AlbumId, prelude::*, ClientCredsSpotify, Credentials}; #[tokio::main] async fn main() { diff --git a/examples/oauth_tokens.rs b/examples/oauth_tokens.rs index 6a1baea3..42da05af 100644 --- a/examples/oauth_tokens.rs +++ b/examples/oauth_tokens.rs @@ -5,7 +5,7 @@ //! an .env file or export them manually as environmental variables for this to //! work. -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; #[tokio::main] async fn main() { diff --git a/examples/pagination_async.rs b/examples/pagination_async.rs index ac01bbbe..2050a270 100644 --- a/examples/pagination_async.rs +++ b/examples/pagination_async.rs @@ -8,7 +8,7 @@ use futures::stream::TryStreamExt; use futures_util::pin_mut; -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; #[tokio::main] async fn main() { diff --git a/examples/pagination_manual.rs b/examples/pagination_manual.rs index a8c6ab0d..f9737512 100644 --- a/examples/pagination_manual.rs +++ b/examples/pagination_manual.rs @@ -1,7 +1,7 @@ //! This example shows how manual pagination works. It's what the raw API //! returns, but harder to use than an iterator or stream. -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; #[tokio::main] async fn main() { diff --git a/examples/with_refresh_token.rs b/examples/with_refresh_token.rs index 772be2fe..111fac3e 100644 --- a/examples/with_refresh_token.rs +++ b/examples/with_refresh_token.rs @@ -15,7 +15,7 @@ //! tokens](https://github.com/felix-hilden/tekore/issues/86), so in the case of //! Spotify it doesn't seem to revoke them at all. -use rspotify::{model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; // Sample request that will follow some artists, print the user's // followed artists, and then unfollow the artists. diff --git a/rspotify-sync/.env b/rspotify-sync/.env new file mode 120000 index 00000000..4a82335f --- /dev/null +++ b/rspotify-sync/.env @@ -0,0 +1 @@ +../.env \ No newline at end of file diff --git a/rspotify-sync/Cargo.toml b/rspotify-sync/Cargo.toml new file mode 100644 index 00000000..7e8fc04a --- /dev/null +++ b/rspotify-sync/Cargo.toml @@ -0,0 +1,84 @@ +[package] +authors = [ + "Ramsay Leung ", + "Mario Ortiz Manero " +] +name = "rspotify-sync" +version = "0.10.0" +license = "MIT" +readme = "../README.md" +description = "Synchronous Spotify API wrapper" +homepage = "https://github.com/ramsayleung/rspotify" +repository = "https://github.com/ramsayleung/rspotify" +keywords = ["spotify", "api"] +edition = "2018" + +[lib] +path = "../src/lib.rs" + +[dependencies] +rspotify-macros = { path = "../rspotify-macros", version = "0.10.0" } +rspotify-model = { path = "../rspotify-model", version = "0.10.0" } +rspotify-http = { path = "../rspotify-http", version = "0.10.0", default-features = false } + +base64 = "0.13.0" +chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } +dotenv = { version = "0.15.0", optional = true } +getrandom = "0.2.3" +log = "0.4.14" +maybe-async = "0.2.6" +serde = { version = "1.0.130", default-features = false } +serde_json = "1.0.67" +thiserror = "1.0.29" +url = "2.2.2" +webbrowser = { version = "0.5.5", optional = true } + +[dev-dependencies] +env_logger = { version = "0.9.0", default-features = false } + +[features] +default = ["client-ureq", "ureq-rustls-tls"] + +### Client ### +cli = ["webbrowser"] +env-file = ["dotenv"] + +### HTTP ### +# Only synchronous clients are listed here. +client-ureq = ["rspotify-http/client-ureq", "__sync"] + +# Passing the TLS features to ureq. +ureq-rustls-tls = ["rspotify-http/ureq-rustls-tls"] + +# Internal features for checking async or sync compilation +__async = [] +__sync = ["maybe-async/is_sync"] + +[package.metadata.docs.rs] +# Documenting the CLI methods, and working links for `dotenv` +features = ["cli", "env-file"] + +[[example]] +name = "pagination_sync" +required-features = ["env-file", "cli"] +path = "examples/pagination_sync.rs" + +[[example]] +name = "device" +required-features = ["env-file", "cli"] +path = "examples/device.rs" + +[[example]] +name = "me" +required-features = ["env-file", "cli"] +path = "examples/me.rs" + +[[example]] +name = "search" +required-features = ["env-file", "cli"] +path = "examples/search.rs" + +[[example]] +name = "seek_track" +required-features = ["env-file", "cli"] +path = "examples/seek_track.rs" diff --git a/examples/ureq/device.rs b/rspotify-sync/examples/device.rs similarity index 86% rename from examples/ureq/device.rs rename to rspotify-sync/examples/device.rs index f4c66dd0..15e5f79e 100644 --- a/examples/ureq/device.rs +++ b/rspotify-sync/examples/device.rs @@ -1,4 +1,4 @@ -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. diff --git a/examples/ureq/me.rs b/rspotify-sync/examples/me.rs similarity index 85% rename from examples/ureq/me.rs rename to rspotify-sync/examples/me.rs index 9258589b..0630b95c 100644 --- a/examples/ureq/me.rs +++ b/rspotify-sync/examples/me.rs @@ -1,4 +1,4 @@ -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. diff --git a/examples/pagination_sync.rs b/rspotify-sync/examples/pagination_sync.rs similarity index 92% rename from examples/pagination_sync.rs rename to rspotify-sync/examples/pagination_sync.rs index 2dd8600e..52389fff 100644 --- a/examples/pagination_sync.rs +++ b/rspotify-sync/examples/pagination_sync.rs @@ -9,7 +9,7 @@ //! } //! ``` -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. diff --git a/examples/ureq/search.rs b/rspotify-sync/examples/search.rs similarity index 99% rename from examples/ureq/search.rs rename to rspotify-sync/examples/search.rs index caab1fae..333f6fc4 100644 --- a/examples/ureq/search.rs +++ b/rspotify-sync/examples/search.rs @@ -1,4 +1,4 @@ -use rspotify::{ +use rspotify_sync::{ model::{Country, Market, SearchType}, prelude::*, ClientCredsSpotify, Credentials, diff --git a/examples/ureq/seek_track.rs b/rspotify-sync/examples/seek_track.rs similarity index 88% rename from examples/ureq/seek_track.rs rename to rspotify-sync/examples/seek_track.rs index a4a98ae1..d6c28685 100644 --- a/examples/ureq/seek_track.rs +++ b/rspotify-sync/examples/seek_track.rs @@ -1,4 +1,4 @@ -use rspotify::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. From 52ee12505ae2c6ecaf84202404b67e32168d550a Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Sun, 19 Sep 2021 21:12:01 +0200 Subject: [PATCH 2/9] More or less fix tests --- Cargo.toml | 1 - rspotify-sync/Cargo.toml | 1 - tests/test_enums.rs | 2 +- tests/test_models.rs | 2 +- tests/test_oauth2.rs | 8 +++- tests/test_with_credential.rs | 50 +++++++++++---------- tests/test_with_oauth.rs | 85 +++++++++++++++++------------------ 7 files changed, 76 insertions(+), 73 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4b9ad7c4..5e3d4a91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,7 +71,6 @@ reqwest-native-tls-vendored = ["rspotify-http/reqwest-native-tls-vendored"] # Internal features for checking async or sync compilation __async = ["futures", "async-stream", "async-trait"] -__sync = [] [package.metadata.docs.rs] # Documenting the CLI methods, and working links for `dotenv` diff --git a/rspotify-sync/Cargo.toml b/rspotify-sync/Cargo.toml index 7e8fc04a..8fc9dd55 100644 --- a/rspotify-sync/Cargo.toml +++ b/rspotify-sync/Cargo.toml @@ -51,7 +51,6 @@ client-ureq = ["rspotify-http/client-ureq", "__sync"] ureq-rustls-tls = ["rspotify-http/ureq-rustls-tls"] # Internal features for checking async or sync compilation -__async = [] __sync = ["maybe-async/is_sync"] [package.metadata.docs.rs] diff --git a/tests/test_enums.rs b/tests/test_enums.rs index e80f65be..41d0a0f9 100644 --- a/tests/test_enums.rs +++ b/tests/test_enums.rs @@ -1,4 +1,4 @@ -use rspotify::model::*; +use rspotify_async::model::*; #[test] fn test_include_external() { diff --git a/tests/test_models.rs b/tests/test_models.rs index 3626db5f..36cb4c6f 100644 --- a/tests/test_models.rs +++ b/tests/test_models.rs @@ -1,5 +1,5 @@ use chrono::{DateTime, NaiveDateTime, Utc}; -use rspotify::model::*; +use rspotify_async::model::*; use std::time::Duration; #[test] diff --git a/tests/test_oauth2.rs b/tests/test_oauth2.rs index 9ce1b8cd..c83fe9d3 100644 --- a/tests/test_oauth2.rs +++ b/tests/test_oauth2.rs @@ -1,6 +1,10 @@ +//! Note that all the endpoint tests should use async only; it is assumed that +//! the async and sync implementations are the same at this point. Keep the +//! sync-specific tests inside the `src` directory. + use chrono::prelude::*; use chrono::Duration; -use rspotify::{ +use rspotify_async::{ prelude::*, scopes, AuthCodeSpotify, ClientCredsSpotify, Config, Credentials, OAuth, Token, }; use std::{collections::HashMap, fs, io::Read, path::PathBuf, thread::sleep}; @@ -32,7 +36,7 @@ fn test_get_authorize_url() { assert_eq!(hash_query.get("state").unwrap(), "fdsafdsfa"); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_read_token_cache() { let expires_in = Duration::seconds(3600); let expires_at = Some(Utc::now() + expires_in); diff --git a/tests/test_with_credential.rs b/tests/test_with_credential.rs index ddf1152b..b7ec6a97 100644 --- a/tests/test_with_credential.rs +++ b/tests/test_with_credential.rs @@ -1,13 +1,14 @@ -use rspotify::{ +//! Note that all the endpoint tests should use async only; it is assumed that +//! the async and sync implementations are the same at this point. Keep the +//! sync-specific tests inside the `src` directory. + +use rspotify_async::{ model::{AlbumId, AlbumType, ArtistId, Country, Id, Market, PlaylistId, TrackId, UserId}, prelude::*, ClientCredsSpotify, Credentials, }; -use maybe_async::maybe_async; - /// Generating a new basic client for the requests. -#[maybe_async] pub async fn creds_client() -> ClientCredsSpotify { // The credentials must be available in the environment. let creds = Credentials::from_env().unwrap_or_else(|| { @@ -23,13 +24,13 @@ pub async fn creds_client() -> ClientCredsSpotify { spotify } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_album() { let birdy_uri = AlbumId::from_uri("spotify:album:0sNOF9WDwhWunNAHPD3Baj").unwrap(); creds_client().await.album(&birdy_uri).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_albums() { let track_uris = [ &AlbumId::from_uri("spotify:album:41MnTivkwTO3UUJ8DrqEJJ").unwrap(), @@ -39,7 +40,7 @@ async fn test_albums() { creds_client().await.albums(track_uris).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_album_tracks() { let birdy_uri = AlbumId::from_uri("spotify:album:6akEvsycLGftJxYudPjmqK").unwrap(); creds_client() @@ -49,7 +50,7 @@ async fn test_album_tracks() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_artist_related_artists() { let birdy_uri = ArtistId::from_uri("spotify:artist:43ZHCT0cAZBISjO8DG9PnE").unwrap(); creds_client() @@ -59,13 +60,13 @@ async fn test_artist_related_artists() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_artist() { let birdy_uri = ArtistId::from_uri("spotify:artist:2WX2uTcsvV5OnS0inACecP").unwrap(); creds_client().await.artist(&birdy_uri).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_artists_albums() { let birdy_uri = ArtistId::from_uri("spotify:artist:2WX2uTcsvV5OnS0inACecP").unwrap(); creds_client() @@ -81,7 +82,7 @@ async fn test_artists_albums() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_artists() { let artist_uris = [ &ArtistId::from_uri("spotify:artist:0oSGxfWSnnOXhD2fKuz2Gy").unwrap(), @@ -90,7 +91,7 @@ async fn test_artists() { creds_client().await.artists(artist_uris).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_artist_top_tracks() { let birdy_uri = ArtistId::from_uri("spotify:artist:2WX2uTcsvV5OnS0inACecP").unwrap(); creds_client() @@ -100,19 +101,19 @@ async fn test_artist_top_tracks() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_audio_analysis() { let track = TrackId::from_id("06AKEBrKUckW0KREUWRnvT").unwrap(); creds_client().await.track_analysis(&track).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_audio_features() { let track = TrackId::from_uri("spotify:track:06AKEBrKUckW0KREUWRnvT").unwrap(); creds_client().await.track_features(&track).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_audios_features() { let mut tracks_ids = vec![]; let track_id1 = TrackId::from_uri("spotify:track:4JpKVNYnVcJ8tuMKjAj50A").unwrap(); @@ -126,19 +127,19 @@ async fn test_audios_features() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_user() { let birdy_uri = UserId::from_id("tuggareutangranser").unwrap(); creds_client().await.user(&birdy_uri).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_track() { let birdy_uri = TrackId::from_uri("spotify:track:6rqhFgbbKwnb9MLmUQDhG6").unwrap(); creds_client().await.track(&birdy_uri).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_tracks() { let track_uris = [ &TrackId::from_uri("spotify:track:3n3Ppam7vgaVa1iaRUc9Lp").unwrap(), @@ -147,7 +148,7 @@ async fn test_tracks() { creds_client().await.tracks(track_uris, None).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_existing_playlist() { let playlist_id = PlaylistId::from_id("37i9dQZF1DZ06evO45P0Eo").unwrap(); creds_client() @@ -157,7 +158,7 @@ async fn test_existing_playlist() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] async fn test_fake_playlist() { let playlist_id = PlaylistId::from_id("fakeid").unwrap(); let playlist = creds_client() @@ -167,6 +168,8 @@ async fn test_fake_playlist() { assert!(!playlist.is_ok()); } +// TODO: move this into the `pagination` module +/* mod test_pagination { use super::*; @@ -184,9 +187,9 @@ mod test_pagination { "Emotion", ]; - /// This test iterates a request of 10 items, with 5 requests of 2 items. - #[cfg(feature = "__sync")] + // This test iterates a request of 10 items, with 5 requests of 2 items. #[test] + #[cfg(feature = "__sync")] fn test_pagination_sync() { let mut client = creds_client(); client.config.pagination_chunks = 2; @@ -201,8 +204,8 @@ mod test_pagination { } /// This test iterates a request of 10 items, with 5 requests of 2 items. - #[cfg(feature = "__async")] #[tokio::test] + #[cfg(feature = "__async")] async fn test_pagination_async() { use futures_util::StreamExt; @@ -219,3 +222,4 @@ mod test_pagination { assert_eq!(names, SONG_NAMES); } } +*/ diff --git a/tests/test_with_oauth.rs b/tests/test_with_oauth.rs index d977650c..37998d41 100644 --- a/tests/test_with_oauth.rs +++ b/tests/test_with_oauth.rs @@ -14,8 +14,12 @@ //! with the `oauth_tokens` example: //! //! cargo run --example oauth_tokens --features=env-file,cli +//! +//! Note that all the endpoint tests should use async only; it is assumed that +//! the async and sync implementations are the same at this point. Keep the +//! sync-specific tests inside the `src` directory. -use rspotify::{ +use rspotify_async::{ clients::pagination::Paginator, model::{ AlbumId, ArtistId, Country, CurrentPlaybackContext, Device, EpisodeId, FullPlaylist, @@ -30,6 +34,7 @@ use std::env; use chrono::prelude::*; use maybe_async::maybe_async; +use futures::stream::TryStreamExt; /// Generating a new OAuth client for the requests. #[maybe_async] @@ -87,22 +92,14 @@ pub async fn oauth_client() -> AuthCodeSpotify { } } -#[maybe_async] async fn fetch_all<'a, T>(paginator: Paginator<'a, ClientResult>) -> Vec { - #[cfg(feature = "__async")] - { - use futures::stream::TryStreamExt; + // TODO: make this into a test in the `paginator` module + // paginator.filter_map(|a| a.ok()).collect::>() - paginator.try_collect::>().await.unwrap() - } - - #[cfg(feature = "__sync")] - { - paginator.filter_map(|a| a.ok()).collect::>() - } + paginator.try_collect::>().await.unwrap() } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_categories() { oauth_client() @@ -117,7 +114,7 @@ async fn test_categories() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_category_playlists() { oauth_client() @@ -132,7 +129,7 @@ async fn test_category_playlists() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_playback() { oauth_client() @@ -142,7 +139,7 @@ async fn test_current_playback() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_playing() { oauth_client() @@ -152,7 +149,7 @@ async fn test_current_playing() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_followed_artists() { oauth_client() @@ -162,7 +159,7 @@ async fn test_current_user_followed_artists() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_playing_track() { oauth_client() @@ -172,7 +169,7 @@ async fn test_current_user_playing_track() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_recently_played() { oauth_client() @@ -182,7 +179,7 @@ async fn test_current_user_recently_played() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_saved_albums() { let album_ids = [ @@ -218,7 +215,7 @@ async fn test_current_user_saved_albums() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_saved_tracks_add() { let tracks_ids = [ @@ -252,7 +249,7 @@ async fn test_current_user_saved_tracks_add() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_top_artists() { oauth_client() @@ -262,7 +259,7 @@ async fn test_current_user_top_artists() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_current_user_top_tracks() { oauth_client() @@ -272,7 +269,7 @@ async fn test_current_user_top_tracks() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_featured_playlists() { let now: DateTime = Utc::now(); @@ -283,13 +280,13 @@ async fn test_featured_playlists() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_me() { oauth_client().await.me().await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_new_releases() { oauth_client() @@ -299,7 +296,7 @@ async fn test_new_releases() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_new_releases_with_from_token() { oauth_client() @@ -309,7 +306,7 @@ async fn test_new_releases_with_from_token() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_playback() { let client = oauth_client().await; @@ -390,7 +387,7 @@ async fn test_playback() { } } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_recommendations() { let seed_artists = [&ArtistId::from_id("4NHQUGzhtTLFvgF5SZesLK").unwrap()]; @@ -414,7 +411,7 @@ async fn test_recommendations() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_repeat() { let client = oauth_client().await; @@ -429,7 +426,7 @@ async fn test_repeat() { } } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_search_album() { let query = "album:arrival artist:abba"; @@ -440,7 +437,7 @@ async fn test_search_album() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_search_artist() { let query = "tania bowra"; @@ -458,7 +455,7 @@ async fn test_search_artist() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_search_playlist() { let query = "\"doom metal\""; @@ -476,7 +473,7 @@ async fn test_search_playlist() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_search_track() { let query = "abba"; @@ -494,7 +491,7 @@ async fn test_search_track() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_seek_track() { let client = oauth_client().await; @@ -516,7 +513,7 @@ async fn test_seek_track() { } } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_shuffle() { let client = oauth_client().await; @@ -531,7 +528,7 @@ async fn test_shuffle() { } } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_user_follow_artist() { let client = oauth_client().await; @@ -544,7 +541,7 @@ async fn test_user_follow_artist() { client.user_unfollow_artists(artists).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_user_follow_users() { let client = oauth_client().await; @@ -557,7 +554,7 @@ async fn test_user_follow_users() { client.user_unfollow_users(users).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_user_follow_playlist() { let client = oauth_client().await; @@ -711,7 +708,7 @@ async fn check_playlist_follow(client: &AuthCodeSpotify, playlist: &FullPlaylist client.playlist_unfollow(&playlist.id).await.unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_playlist() { let client = oauth_client().await; @@ -721,7 +718,7 @@ async fn test_playlist() { check_playlist_follow(&client, &playlist).await; } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_volume() { let client = oauth_client().await; @@ -743,7 +740,7 @@ async fn test_volume() { } } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_add_queue() { // NOTE: unfortunately it's impossible to revert this test @@ -756,7 +753,7 @@ async fn test_add_queue() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_get_several_shows() { let shows = [ @@ -771,7 +768,7 @@ async fn test_get_several_shows() { .unwrap(); } -#[maybe_async::test(feature = "__sync", async(feature = "__async", tokio::test))] +#[tokio::test] #[ignore] async fn test_get_several_episodes() { let episodes = [ From 6b0c8cb7baa8f19f0529a4b4cc994a9acde057d3 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Sun, 19 Sep 2021 21:33:53 +0200 Subject: [PATCH 3/9] Generic client --- rspotify-http/src/common.rs | 2 +- rspotify-http/src/lib.rs | 31 +------------------------------ src/auth_code.rs | 14 +++++++------- src/auth_code_pkce.rs | 14 +++++++------- src/client_creds.rs | 12 ++++++------ src/clients/base.rs | 7 ++++--- src/clients/oauth.rs | 7 +++++-- 7 files changed, 31 insertions(+), 56 deletions(-) diff --git a/rspotify-http/src/common.rs b/rspotify-http/src/common.rs index 9734bb36..84e077d2 100644 --- a/rspotify-http/src/common.rs +++ b/rspotify-http/src/common.rs @@ -43,7 +43,7 @@ pub type HttpResult = Result; /// redundancy and edge cases (a `Some(Value::Null), for example, doesn't make /// much sense). #[maybe_async] -pub trait BaseHttpClient: Send + Default + Clone + fmt::Debug { +pub trait BaseHttpClient: Send + Sync + Default + Clone + fmt::Debug { // This internal function should always be given an object value in JSON. async fn get( &self, diff --git a/rspotify-http/src/lib.rs b/rspotify-http/src/lib.rs index ced8acdd..ce8aa3e6 100644 --- a/rspotify-http/src/lib.rs +++ b/rspotify-http/src/lib.rs @@ -5,39 +5,10 @@ // This way only the compile error below gets shown instead of a whole list of // confusing errors.. +mod common; #[cfg(feature = "client-reqwest")] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] mod reqwest; - #[cfg(feature = "client-ureq")] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] mod ureq; -#[cfg(any(feature = "client-reqwest", feature = "client-ureq"))] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] -mod common; - -#[cfg(feature = "client-reqwest")] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] -pub use self::reqwest::ReqwestClient as HttpClient; - -#[cfg(feature = "client-ureq")] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] -pub use self::ureq::UreqClient as HttpClient; - -#[cfg(any(feature = "client-reqwest", feature = "client-ureq"))] -#[cfg(not(all(feature = "client-reqwest", feature = "client-ureq")))] pub use common::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; - -#[cfg(all(feature = "client-reqwest", feature = "client-ureq"))] -compile_error!( - "`client-reqwest` and `client-ureq` features cannot both be enabled at \ - the same time, if you want to use `client-ureq` you need to set \ - `default-features = false`" -); - -#[cfg(not(any(feature = "client-reqwest", feature = "client-ureq")))] -compile_error!( - "You have to enable at least one of the available clients with the \ - `client-reqwest` or `client-ureq` features." -); diff --git a/src/auth_code.rs b/src/auth_code.rs index bfe5942b..0529d571 100644 --- a/src/auth_code.rs +++ b/src/auth_code.rs @@ -2,7 +2,7 @@ use crate::{ auth_urls, clients::{BaseClient, OAuthClient}, headers, - http::{Form, HttpClient}, + http::{BaseHttpClient, Form}, ClientResult, Config, Credentials, OAuth, Token, }; @@ -61,18 +61,18 @@ use url::Url; /// [example-webapp]: https://github.com/ramsayleung/rspotify/tree/master/examples/webapp /// [example-refresh-token]: https://github.com/ramsayleung/rspotify/blob/master/examples/with_refresh_token.rs #[derive(Clone, Debug, Default)] -pub struct AuthCodeSpotify { +pub struct AuthCodeSpotify { pub creds: Credentials, pub oauth: OAuth, pub config: Config, pub token: Option, - pub(in crate) http: HttpClient, + pub(in crate) http: Http, } /// This client has access to the base methods. #[maybe_async] -impl BaseClient for AuthCodeSpotify { - fn get_http(&self) -> &HttpClient { +impl BaseClient for AuthCodeSpotify { + fn get_http(&self) -> &Http { &self.http } @@ -96,7 +96,7 @@ impl BaseClient for AuthCodeSpotify { /// This client includes user authorization, so it has access to the user /// private endpoints in [`OAuthClient`]. #[maybe_async] -impl OAuthClient for AuthCodeSpotify { +impl OAuthClient for AuthCodeSpotify { fn get_oauth(&self) -> &OAuth { &self.oauth } @@ -140,7 +140,7 @@ impl OAuthClient for AuthCodeSpotify { } } -impl AuthCodeSpotify { +impl AuthCodeSpotify { /// Builds a new [`AuthCodeSpotify`] given a pair of client credentials and /// OAuth information. pub fn new(creds: Credentials, oauth: OAuth) -> Self { diff --git a/src/auth_code_pkce.rs b/src/auth_code_pkce.rs index 7bcaf6cb..b0fb1899 100644 --- a/src/auth_code_pkce.rs +++ b/src/auth_code_pkce.rs @@ -2,7 +2,7 @@ use crate::{ auth_urls, clients::{BaseClient, OAuthClient}, headers, - http::{Form, HttpClient}, + http::{BaseHttpClient, Form}, ClientResult, Config, Credentials, OAuth, Token, }; @@ -25,17 +25,17 @@ use url::Url; /// [reference]: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow-with-proof-key-for-code-exchange-pkce /// [example-main]: https://github.com/ramsayleung/rspotify/blob/master/examples/auth_code_pkce.rs #[derive(Clone, Debug, Default)] -pub struct AuthCodePkceSpotify { +pub struct AuthCodePkceSpotify { pub creds: Credentials, pub oauth: OAuth, pub config: Config, pub token: Option, - pub(in crate) http: HttpClient, + pub(in crate) http: Http, } /// This client has access to the base methods. -impl BaseClient for AuthCodePkceSpotify { - fn get_http(&self) -> &HttpClient { +impl BaseClient for AuthCodePkceSpotify { + fn get_http(&self) -> &Http { &self.http } @@ -59,7 +59,7 @@ impl BaseClient for AuthCodePkceSpotify { /// This client includes user authorization, so it has access to the user /// private endpoints in [`OAuthClient`]. #[maybe_async] -impl OAuthClient for AuthCodePkceSpotify { +impl OAuthClient for AuthCodePkceSpotify { fn get_oauth(&self) -> &OAuth { &self.oauth } @@ -100,7 +100,7 @@ impl OAuthClient for AuthCodePkceSpotify { } } -impl AuthCodePkceSpotify { +impl AuthCodePkceSpotify { /// Builds a new [`AuthCodePkceSpotify`] given a pair of client credentials /// and OAuth information. pub fn new(creds: Credentials, oauth: OAuth) -> Self { diff --git a/src/client_creds.rs b/src/client_creds.rs index f808cab4..c2c1bb1f 100644 --- a/src/client_creds.rs +++ b/src/client_creds.rs @@ -1,7 +1,7 @@ use crate::{ clients::BaseClient, headers, - http::{Form, HttpClient}, + http::{BaseHttpClient, Form}, ClientResult, Config, Credentials, Token, }; @@ -20,16 +20,16 @@ use maybe_async::maybe_async; /// [reference]: https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow /// [example-main]: https://github.com/ramsayleung/rspotify/blob/master/examples/client_creds.rs #[derive(Clone, Debug, Default)] -pub struct ClientCredsSpotify { +pub struct ClientCredsSpotify { pub config: Config, pub creds: Credentials, pub token: Option, - pub(in crate) http: HttpClient, + pub(in crate) http: Http, } /// This client has access to the base methods. -impl BaseClient for ClientCredsSpotify { - fn get_http(&self) -> &HttpClient { +impl BaseClient for ClientCredsSpotify { + fn get_http(&self) -> &Http { &self.http } @@ -50,7 +50,7 @@ impl BaseClient for ClientCredsSpotify { } } -impl ClientCredsSpotify { +impl ClientCredsSpotify { /// Builds a new [`ClientCredsSpotify`] given a pair of client credentials /// and OAuth information. pub fn new(creds: Credentials) -> Self { diff --git a/src/clients/base.rs b/src/clients/base.rs index 78aa4547..448a9520 100644 --- a/src/clients/base.rs +++ b/src/clients/base.rs @@ -4,7 +4,7 @@ use crate::{ basic_auth, bearer_auth, convert_result, join_ids, pagination::{paginate, Paginator}, }, - http::{BaseHttpClient, Form, Headers, HttpClient, Query}, + http::{BaseHttpClient, Form, Headers, Query}, macros::build_map, model::*, ClientResult, Config, Credentials, Token, @@ -20,12 +20,13 @@ use serde_json::Value; /// accessed without user authorization, including parts of the authentication /// flow that are shared, and the endpoints. #[maybe_async] -pub trait BaseClient +pub trait BaseClient where + Http: BaseHttpClient, Self: Send + Sync + Default + Clone + fmt::Debug, { fn get_config(&self) -> &Config; - fn get_http(&self) -> &HttpClient; + fn get_http(&self) -> &Http; fn get_token(&self) -> Option<&Token>; fn get_token_mut(&mut self) -> Option<&mut Token>; fn get_creds(&self) -> &Credentials; diff --git a/src/clients/oauth.rs b/src/clients/oauth.rs index 1787d0aa..84b7e63a 100644 --- a/src/clients/oauth.rs +++ b/src/clients/oauth.rs @@ -4,7 +4,7 @@ use crate::{ pagination::{paginate, Paginator}, BaseClient, }, - http::Query, + http::{BaseHttpClient, Query}, macros::{build_json, build_map}, model::*, ClientResult, OAuth, Token, @@ -27,7 +27,10 @@ use url::Url; /// only separates endpoints that *always* need authorization from the base /// ones. #[maybe_async] -pub trait OAuthClient: BaseClient { +pub trait OAuthClient: BaseClient +where + Http: BaseHttpClient, +{ fn get_oauth(&self) -> &OAuth; /// Obtains a user access token given a code, as part of the OAuth From 9861d5590d3b8ef60da15934823fcbabddd7f8e2 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Sun, 19 Sep 2021 21:55:29 +0200 Subject: [PATCH 4/9] Fix examples and tests --- examples/auth_code.rs | 3 ++- examples/auth_code_pkce.rs | 4 ++-- examples/client_creds.rs | 4 ++-- examples/oauth_tokens.rs | 4 ++-- examples/pagination_async.rs | 4 ++-- examples/pagination_manual.rs | 4 ++-- examples/with_refresh_token.rs | 4 ++-- rspotify-http/src/lib.rs | 6 ++++++ rspotify-http/src/reqwest.rs | 6 +++--- rspotify-http/src/ureq.rs | 6 +++--- rspotify-sync/examples/device.rs | 4 ++-- rspotify-sync/examples/me.rs | 4 ++-- rspotify-sync/examples/pagination_sync.rs | 4 ++-- rspotify-sync/examples/search.rs | 3 ++- rspotify-sync/examples/seek_track.rs | 4 ++-- src/clients/mod.rs | 6 +++--- src/lib.rs | 5 +++++ tests/test_oauth2.rs | 11 ++++++----- tests/test_with_credential.rs | 3 ++- tests/test_with_oauth.rs | 3 ++- 20 files changed, 54 insertions(+), 38 deletions(-) diff --git a/examples/auth_code.rs b/examples/auth_code.rs index 01a51b8c..ff5bf694 100644 --- a/examples/auth_code.rs +++ b/examples/auth_code.rs @@ -2,6 +2,7 @@ use rspotify_async::{ model::{AdditionalType, Country, Market}, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, + http::ReqwestClient }; #[tokio::main] @@ -38,7 +39,7 @@ async fn main() { // ``` let oauth = OAuth::from_env(scopes!("user-read-currently-playing")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/examples/auth_code_pkce.rs b/examples/auth_code_pkce.rs index 0f4add50..8e23f85e 100644 --- a/examples/auth_code_pkce.rs +++ b/examples/auth_code_pkce.rs @@ -1,4 +1,4 @@ -use rspotify_async::{prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth, http::ReqwestClient}; #[tokio::main] async fn main() { @@ -34,7 +34,7 @@ async fn main() { // ``` let oauth = OAuth::from_env(scopes!("user-read-recently-played")).unwrap(); - let mut spotify = AuthCodePkceSpotify::new(creds, oauth); + let mut spotify = AuthCodePkceSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url().unwrap(); diff --git a/examples/client_creds.rs b/examples/client_creds.rs index 8febb1e5..6f26d16e 100644 --- a/examples/client_creds.rs +++ b/examples/client_creds.rs @@ -1,4 +1,4 @@ -use rspotify_async::{model::AlbumId, prelude::*, ClientCredsSpotify, Credentials}; +use rspotify_async::{model::AlbumId, prelude::*, ClientCredsSpotify, Credentials, http::ReqwestClient}; #[tokio::main] async fn main() { @@ -23,7 +23,7 @@ async fn main() { // ``` let creds = Credentials::from_env().unwrap(); - let mut spotify = ClientCredsSpotify::new(creds); + let mut spotify = ClientCredsSpotify::::new(creds); // Obtaining the access token. Requires to be mutable because the internal // token will be modified. We don't need OAuth for this specific endpoint, diff --git a/examples/oauth_tokens.rs b/examples/oauth_tokens.rs index 42da05af..311bf868 100644 --- a/examples/oauth_tokens.rs +++ b/examples/oauth_tokens.rs @@ -5,7 +5,7 @@ //! an .env file or export them manually as environmental variables for this to //! work. -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; #[tokio::main] async fn main() { @@ -38,7 +38,7 @@ async fn main() { ); let oauth = OAuth::from_env(scopes).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); let url = spotify.get_authorize_url(false).unwrap(); spotify.prompt_for_token(&url).await.unwrap(); diff --git a/examples/pagination_async.rs b/examples/pagination_async.rs index 2050a270..f3cb8478 100644 --- a/examples/pagination_async.rs +++ b/examples/pagination_async.rs @@ -8,7 +8,7 @@ use futures::stream::TryStreamExt; use futures_util::pin_mut; -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; #[tokio::main] async fn main() { @@ -18,7 +18,7 @@ async fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-library-read")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/examples/pagination_manual.rs b/examples/pagination_manual.rs index f9737512..b739dcbc 100644 --- a/examples/pagination_manual.rs +++ b/examples/pagination_manual.rs @@ -1,7 +1,7 @@ //! This example shows how manual pagination works. It's what the raw API //! returns, but harder to use than an iterator or stream. -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; #[tokio::main] async fn main() { @@ -11,7 +11,7 @@ async fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-library-read")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/examples/with_refresh_token.rs b/examples/with_refresh_token.rs index 111fac3e..25654ffd 100644 --- a/examples/with_refresh_token.rs +++ b/examples/with_refresh_token.rs @@ -15,7 +15,7 @@ //! tokens](https://github.com/felix-hilden/tekore/issues/86), so in the case of //! Spotify it doesn't seem to revoke them at all. -use rspotify_async::{model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_async::{model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; // Sample request that will follow some artists, print the user's // followed artists, and then unfollow the artists. @@ -56,7 +56,7 @@ async fn main() { // The default credentials from the `.env` file will be used by default. let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-follow-read user-follow-modify")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds.clone(), oauth.clone()); + let mut spotify = AuthCodeSpotify::::new(creds.clone(), oauth.clone()); // In the first session of the application we authenticate and obtain the // refresh token. We can also do some requests here. diff --git a/rspotify-http/src/lib.rs b/rspotify-http/src/lib.rs index ce8aa3e6..4e29a8bd 100644 --- a/rspotify-http/src/lib.rs +++ b/rspotify-http/src/lib.rs @@ -6,9 +6,15 @@ // confusing errors.. mod common; + #[cfg(feature = "client-reqwest")] mod reqwest; +#[cfg(feature = "client-reqwest")] +pub use self::reqwest::ReqwestClient; + #[cfg(feature = "client-ureq")] mod ureq; +#[cfg(feature = "client-ureq")] +pub use self::ureq::UreqClient; pub use common::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; diff --git a/rspotify-http/src/reqwest.rs b/rspotify-http/src/reqwest.rs index a08e893f..40b46fe7 100644 --- a/rspotify-http/src/reqwest.rs +++ b/rspotify-http/src/reqwest.rs @@ -1,7 +1,7 @@ //! The client implementation for the reqwest HTTP client, which is async by //! default. -use super::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; +use crate::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; use std::convert::TryInto; @@ -11,7 +11,7 @@ use rspotify_model::ApiError; use serde_json::Value; impl HttpError { - pub async fn from_response(response: reqwest::Response) -> Self { + pub async fn from_reqwest(response: reqwest::Response) -> Self { match response.status() { StatusCode::UNAUTHORIZED => Self::Unauthorized, StatusCode::TOO_MANY_REQUESTS => Self::RateLimited( @@ -88,7 +88,7 @@ impl ReqwestClient { if response.status().is_success() { response.text().await.map_err(Into::into) } else { - Err(HttpError::from_response(response).await) + Err(HttpError::from_reqwest(response).await) } } } diff --git a/rspotify-http/src/ureq.rs b/rspotify-http/src/ureq.rs index 2f2cecc0..c8e3ac16 100644 --- a/rspotify-http/src/ureq.rs +++ b/rspotify-http/src/ureq.rs @@ -1,13 +1,13 @@ //! The client implementation for the ureq HTTP client, which is blocking. -use super::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; +use crate::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; use maybe_async::sync_impl; use serde_json::Value; use ureq::{Request, Response}; impl HttpError { - pub fn from_response(r: ureq::Response) -> Self { + pub fn from_ureq(r: ureq::Response) -> Self { HttpError::StatusCode(r.status(), r.status_text().to_string()) } } @@ -45,7 +45,7 @@ impl UreqClient { // Successful request Ok(response) => response.into_string().map_err(Into::into), // HTTP status error - Err(ureq::Error::Status(_, response)) => Err(HttpError::from_response(response)), + Err(ureq::Error::Status(_, response)) => Err(HttpError::from_ureq(response)), // Some kind of IO/transport error Err(err) => Err(HttpError::Request(err.to_string())), } diff --git a/rspotify-sync/examples/device.rs b/rspotify-sync/examples/device.rs index 15e5f79e..6bc7f325 100644 --- a/rspotify-sync/examples/device.rs +++ b/rspotify-sync/examples/device.rs @@ -1,4 +1,4 @@ -use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{http::UreqClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. @@ -7,7 +7,7 @@ fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-read-playback-state")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/rspotify-sync/examples/me.rs b/rspotify-sync/examples/me.rs index 0630b95c..673fc9d5 100644 --- a/rspotify-sync/examples/me.rs +++ b/rspotify-sync/examples/me.rs @@ -1,4 +1,4 @@ -use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{http::UreqClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. @@ -7,7 +7,7 @@ fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-read-playback-state")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/rspotify-sync/examples/pagination_sync.rs b/rspotify-sync/examples/pagination_sync.rs index 52389fff..b526fd01 100644 --- a/rspotify-sync/examples/pagination_sync.rs +++ b/rspotify-sync/examples/pagination_sync.rs @@ -9,7 +9,7 @@ //! } //! ``` -use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{http::UreqClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. @@ -18,7 +18,7 @@ fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-library-read")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/rspotify-sync/examples/search.rs b/rspotify-sync/examples/search.rs index 333f6fc4..31de5384 100644 --- a/rspotify-sync/examples/search.rs +++ b/rspotify-sync/examples/search.rs @@ -1,4 +1,5 @@ use rspotify_sync::{ + http::UreqClient, model::{Country, Market, SearchType}, prelude::*, ClientCredsSpotify, Credentials, @@ -9,7 +10,7 @@ fn main() { env_logger::init(); let creds = Credentials::from_env().unwrap(); - let mut spotify = ClientCredsSpotify::new(creds); + let mut spotify = ClientCredsSpotify::::new(creds); // Obtaining the access token spotify.request_token().unwrap(); diff --git a/rspotify-sync/examples/seek_track.rs b/rspotify-sync/examples/seek_track.rs index d6c28685..5c062592 100644 --- a/rspotify-sync/examples/seek_track.rs +++ b/rspotify-sync/examples/seek_track.rs @@ -1,4 +1,4 @@ -use rspotify_sync::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; +use rspotify_sync::{http::UreqClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth}; fn main() { // You can use any logger for debugging. @@ -7,7 +7,7 @@ fn main() { let creds = Credentials::from_env().unwrap(); let oauth = OAuth::from_env(scopes!("user-read-playback-state")).unwrap(); - let mut spotify = AuthCodeSpotify::new(creds, oauth); + let mut spotify = AuthCodeSpotify::::new(creds, oauth); // Obtaining the access token let url = spotify.get_authorize_url(false).unwrap(); diff --git a/src/clients/mod.rs b/src/clients/mod.rs index 7f28ee4f..b59c63c8 100644 --- a/src/clients/mod.rs +++ b/src/clients/mod.rs @@ -55,7 +55,7 @@ pub fn basic_auth(user: &str, password: &str) -> (String, String) { #[cfg(test)] mod test { use super::*; - use crate::{scopes, ClientCredsSpotify, Token}; + use crate::{scopes, ClientCredsSpotify, TestClient, Token}; use chrono::{prelude::*, Duration}; #[test] @@ -98,7 +98,7 @@ mod test { #[test] fn test_endpoint_url() { - let spotify = ClientCredsSpotify::default(); + let spotify = ClientCredsSpotify::::default(); assert_eq!( spotify.endpoint_url("me/player/play"), "https://api.spotify.com/v1/me/player/play" @@ -123,7 +123,7 @@ mod test { refresh_token: Some("...".to_string()), }; - let spotify = ClientCredsSpotify::from_token(tok); + let spotify = ClientCredsSpotify::::from_token(tok); let headers = spotify.auth_headers().unwrap(); assert_eq!( headers.get("authorization"), diff --git a/src/lib.rs b/src/lib.rs index 44d06fe3..63de996d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,6 +137,11 @@ pub use client_creds::ClientCredsSpotify; pub use macros::scopes; pub use model::Token; +#[cfg(feature = "__async")] +pub(in crate) use http::ReqwestClient as TestClient; +#[cfg(feature = "__sync")] +pub(in crate) use http::UreqClient as TestClient; + use crate::http::HttpError; use std::{collections::HashSet, env, path::PathBuf}; diff --git a/tests/test_oauth2.rs b/tests/test_oauth2.rs index c83fe9d3..21438d6c 100644 --- a/tests/test_oauth2.rs +++ b/tests/test_oauth2.rs @@ -6,6 +6,7 @@ use chrono::prelude::*; use chrono::Duration; use rspotify_async::{ prelude::*, scopes, AuthCodeSpotify, ClientCredsSpotify, Config, Credentials, OAuth, Token, + http::ReqwestClient }; use std::{collections::HashMap, fs, io::Read, path::PathBuf, thread::sleep}; use url::Url; @@ -20,7 +21,7 @@ fn test_get_authorize_url() { }; let creds = Credentials::new("this-is-my-client-id", "this-is-my-client-secret"); - let spotify = AuthCodeSpotify::new(creds, oauth); + let spotify = AuthCodeSpotify::::new(creds, oauth); let authorize_url = spotify.get_authorize_url(false).unwrap(); let hash_query: HashMap<_, _> = Url::parse(&authorize_url) @@ -55,14 +56,14 @@ async fn test_read_token_cache() { cache_path: PathBuf::from(".test_read_token_cache.json"), ..Default::default() }; - let mut predefined_spotify = ClientCredsSpotify::from_token(tok.clone()); + let mut predefined_spotify = ClientCredsSpotify::::from_token(tok.clone()); predefined_spotify.config = config.clone(); // write token data to cache_path predefined_spotify.write_token_cache().unwrap(); assert!(predefined_spotify.config.cache_path.exists()); - let mut spotify = ClientCredsSpotify::default(); + let mut spotify = ClientCredsSpotify::::default(); spotify.config = config; // read token from cache file @@ -94,7 +95,7 @@ fn test_write_token() { cache_path: PathBuf::from(".test_write_token_cache.json"), ..Default::default() }; - let mut spotify = ClientCredsSpotify::from_token(tok.clone()); + let mut spotify = ClientCredsSpotify::::from_token(tok.clone()); spotify.config = config; let tok_str = serde_json::to_string(&tok).unwrap(); @@ -130,7 +131,7 @@ fn test_token_is_expired() { #[test] fn test_parse_response_code() { - let spotify = AuthCodeSpotify::default(); + let spotify = AuthCodeSpotify::::default(); let url = "http://localhost:8888/callback"; let code = spotify.parse_response_code(url); diff --git a/tests/test_with_credential.rs b/tests/test_with_credential.rs index b7ec6a97..43358f2a 100644 --- a/tests/test_with_credential.rs +++ b/tests/test_with_credential.rs @@ -6,6 +6,7 @@ use rspotify_async::{ model::{AlbumId, AlbumType, ArtistId, Country, Id, Market, PlaylistId, TrackId, UserId}, prelude::*, ClientCredsSpotify, Credentials, + http::ReqwestClient }; /// Generating a new basic client for the requests. @@ -19,7 +20,7 @@ pub async fn creds_client() -> ClientCredsSpotify { ) }); - let mut spotify = ClientCredsSpotify::new(creds); + let mut spotify = ClientCredsSpotify::::new(creds); spotify.request_token().await.unwrap(); spotify } diff --git a/tests/test_with_oauth.rs b/tests/test_with_oauth.rs index 37998d41..30d1cfb2 100644 --- a/tests/test_with_oauth.rs +++ b/tests/test_with_oauth.rs @@ -28,6 +28,7 @@ use rspotify_async::{ }, prelude::*, scopes, AuthCodeSpotify, ClientResult, Credentials, OAuth, Token, + http::ReqwestClient }; use std::env; @@ -45,7 +46,7 @@ pub async fn oauth_client() -> AuthCodeSpotify { ..Default::default() }; - AuthCodeSpotify::from_token(tok) + AuthCodeSpotify::::from_token(tok) } else if let Ok(refresh_token) = env::var("RSPOTIFY_REFRESH_TOKEN") { // The credentials must be available in the environment. Enable // `env-file` in order to read them from an `.env` file. From c35ab7e3e8e7e118cc1f1b8e82eddf510404b7aa Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Mon, 20 Sep 2021 23:15:11 +0200 Subject: [PATCH 5/9] More or less fix tests and formatting --- examples/auth_code.rs | 2 +- examples/auth_code_pkce.rs | 4 +++- examples/client_creds.rs | 4 +++- examples/oauth_tokens.rs | 4 +++- examples/pagination_async.rs | 4 +++- examples/pagination_manual.rs | 4 +++- examples/with_refresh_token.rs | 6 ++++-- src/lib.rs | 6 ++++-- tests/test_oauth2.rs | 4 ++-- tests/test_with_credential.rs | 6 +++--- tests/test_with_oauth.rs | 24 +++++++++++------------- 11 files changed, 40 insertions(+), 28 deletions(-) diff --git a/examples/auth_code.rs b/examples/auth_code.rs index ff5bf694..26869995 100644 --- a/examples/auth_code.rs +++ b/examples/auth_code.rs @@ -1,8 +1,8 @@ use rspotify_async::{ + http::ReqwestClient, model::{AdditionalType, Country, Market}, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, - http::ReqwestClient }; #[tokio::main] diff --git a/examples/auth_code_pkce.rs b/examples/auth_code_pkce.rs index 8e23f85e..2d7558f0 100644 --- a/examples/auth_code_pkce.rs +++ b/examples/auth_code_pkce.rs @@ -1,4 +1,6 @@ -use rspotify_async::{prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, prelude::*, scopes, AuthCodePkceSpotify, Credentials, OAuth, +}; #[tokio::main] async fn main() { diff --git a/examples/client_creds.rs b/examples/client_creds.rs index 6f26d16e..d3f10fa2 100644 --- a/examples/client_creds.rs +++ b/examples/client_creds.rs @@ -1,4 +1,6 @@ -use rspotify_async::{model::AlbumId, prelude::*, ClientCredsSpotify, Credentials, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, model::AlbumId, prelude::*, ClientCredsSpotify, Credentials, +}; #[tokio::main] async fn main() { diff --git a/examples/oauth_tokens.rs b/examples/oauth_tokens.rs index 311bf868..fece91dc 100644 --- a/examples/oauth_tokens.rs +++ b/examples/oauth_tokens.rs @@ -5,7 +5,9 @@ //! an .env file or export them manually as environmental variables for this to //! work. -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, +}; #[tokio::main] async fn main() { diff --git a/examples/pagination_async.rs b/examples/pagination_async.rs index f3cb8478..754c4c70 100644 --- a/examples/pagination_async.rs +++ b/examples/pagination_async.rs @@ -8,7 +8,9 @@ use futures::stream::TryStreamExt; use futures_util::pin_mut; -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, +}; #[tokio::main] async fn main() { diff --git a/examples/pagination_manual.rs b/examples/pagination_manual.rs index b739dcbc..90e7711c 100644 --- a/examples/pagination_manual.rs +++ b/examples/pagination_manual.rs @@ -1,7 +1,9 @@ //! This example shows how manual pagination works. It's what the raw API //! returns, but harder to use than an iterator or stream. -use rspotify_async::{prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, +}; #[tokio::main] async fn main() { diff --git a/examples/with_refresh_token.rs b/examples/with_refresh_token.rs index 25654ffd..add90434 100644 --- a/examples/with_refresh_token.rs +++ b/examples/with_refresh_token.rs @@ -15,11 +15,13 @@ //! tokens](https://github.com/felix-hilden/tekore/issues/86), so in the case of //! Spotify it doesn't seem to revoke them at all. -use rspotify_async::{model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, http::ReqwestClient}; +use rspotify_async::{ + http::ReqwestClient, model::ArtistId, prelude::*, scopes, AuthCodeSpotify, Credentials, OAuth, +}; // Sample request that will follow some artists, print the user's // followed artists, and then unfollow the artists. -async fn do_things(spotify: AuthCodeSpotify) { +async fn do_things(spotify: AuthCodeSpotify) { let artists = [ &ArtistId::from_id("3RGLhK1IP9jnYFH4BRFJBS").unwrap(), // The Clash &ArtistId::from_id("0yNLKJebCb8Aueb54LYya3").unwrap(), // New Order diff --git a/src/lib.rs b/src/lib.rs index 63de996d..f921a1dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,9 +137,11 @@ pub use client_creds::ClientCredsSpotify; pub use macros::scopes; pub use model::Token; -#[cfg(feature = "__async")] +#[cfg(all(test, feature = "__async", not(feature = "__sync")))] pub(in crate) use http::ReqwestClient as TestClient; -#[cfg(feature = "__sync")] +#[cfg(all(test, feature = "__async", feature = "__sync"))] +pub(in crate) use http::ReqwestClient as TestClient; +#[cfg(all(test, feature = "__sync", not(feature = "__async")))] pub(in crate) use http::UreqClient as TestClient; use crate::http::HttpError; diff --git a/tests/test_oauth2.rs b/tests/test_oauth2.rs index 21438d6c..c0ed5dba 100644 --- a/tests/test_oauth2.rs +++ b/tests/test_oauth2.rs @@ -5,8 +5,8 @@ use chrono::prelude::*; use chrono::Duration; use rspotify_async::{ - prelude::*, scopes, AuthCodeSpotify, ClientCredsSpotify, Config, Credentials, OAuth, Token, - http::ReqwestClient + http::ReqwestClient, prelude::*, scopes, AuthCodeSpotify, ClientCredsSpotify, Config, + Credentials, OAuth, Token, }; use std::{collections::HashMap, fs, io::Read, path::PathBuf, thread::sleep}; use url::Url; diff --git a/tests/test_with_credential.rs b/tests/test_with_credential.rs index 43358f2a..dbb4331c 100644 --- a/tests/test_with_credential.rs +++ b/tests/test_with_credential.rs @@ -3,14 +3,14 @@ //! sync-specific tests inside the `src` directory. use rspotify_async::{ + http::ReqwestClient, model::{AlbumId, AlbumType, ArtistId, Country, Id, Market, PlaylistId, TrackId, UserId}, prelude::*, ClientCredsSpotify, Credentials, - http::ReqwestClient }; /// Generating a new basic client for the requests. -pub async fn creds_client() -> ClientCredsSpotify { +pub async fn creds_client() -> ClientCredsSpotify { // The credentials must be available in the environment. let creds = Credentials::from_env().unwrap_or_else(|| { panic!( @@ -20,7 +20,7 @@ pub async fn creds_client() -> ClientCredsSpotify { ) }); - let mut spotify = ClientCredsSpotify::::new(creds); + let mut spotify = ClientCredsSpotify::new(creds); spotify.request_token().await.unwrap(); spotify } diff --git a/tests/test_with_oauth.rs b/tests/test_with_oauth.rs index 30d1cfb2..4e104e69 100644 --- a/tests/test_with_oauth.rs +++ b/tests/test_with_oauth.rs @@ -21,6 +21,7 @@ use rspotify_async::{ clients::pagination::Paginator, + http::ReqwestClient, model::{ AlbumId, ArtistId, Country, CurrentPlaybackContext, Device, EpisodeId, FullPlaylist, Market, Offset, PlaylistId, RecommendationsAttribute, RepeatState, SearchType, ShowId, @@ -28,25 +29,22 @@ use rspotify_async::{ }, prelude::*, scopes, AuthCodeSpotify, ClientResult, Credentials, OAuth, Token, - http::ReqwestClient }; use std::env; use chrono::prelude::*; -use maybe_async::maybe_async; use futures::stream::TryStreamExt; /// Generating a new OAuth client for the requests. -#[maybe_async] -pub async fn oauth_client() -> AuthCodeSpotify { +pub async fn oauth_client() -> AuthCodeSpotify { if let Ok(access_token) = env::var("RSPOTIFY_ACCESS_TOKEN") { let tok = Token { access_token, ..Default::default() }; - AuthCodeSpotify::::from_token(tok) + AuthCodeSpotify::from_token(tok) } else if let Ok(refresh_token) = env::var("RSPOTIFY_REFRESH_TOKEN") { // The credentials must be available in the environment. Enable // `env-file` in order to read them from an `.env` file. @@ -569,8 +567,7 @@ async fn test_user_follow_playlist() { client.playlist_unfollow(&playlist_id).await.unwrap(); } -#[maybe_async] -async fn check_playlist_create(client: &AuthCodeSpotify) -> FullPlaylist { +async fn check_playlist_create(client: &AuthCodeSpotify) -> FullPlaylist { let user = client.me().await.unwrap(); let name = "A New Playlist"; @@ -607,14 +604,16 @@ async fn check_playlist_create(client: &AuthCodeSpotify) -> FullPlaylist { playlist } -#[maybe_async] -async fn check_num_tracks(client: &AuthCodeSpotify, playlist_id: &PlaylistId, num: i32) { +async fn check_num_tracks( + client: &AuthCodeSpotify, + playlist_id: &PlaylistId, + num: i32, +) { let fetched_tracks = fetch_all(client.playlist_tracks(playlist_id, None, None)).await; assert_eq!(fetched_tracks.len() as i32, num); } -#[maybe_async] -async fn check_playlist_tracks(client: &AuthCodeSpotify, playlist: &FullPlaylist) { +async fn check_playlist_tracks(client: &AuthCodeSpotify, playlist: &FullPlaylist) { // The tracks in the playlist, some of them repeated // TODO: include episodes after https://github.com/ramsayleung/rspotify/issues/203 let tracks = [ @@ -691,8 +690,7 @@ async fn check_playlist_tracks(client: &AuthCodeSpotify, playlist: &FullPlaylist check_num_tracks(client, &playlist.id, replaced_tracks.len() as i32 - 5).await; } -#[maybe_async] -async fn check_playlist_follow(client: &AuthCodeSpotify, playlist: &FullPlaylist) { +async fn check_playlist_follow(client: &AuthCodeSpotify, playlist: &FullPlaylist) { let user_ids = [ &UserId::from_id("possan").unwrap(), &UserId::from_id("elogain").unwrap(), From f151a096c9ee67173b2ce7bdde929eae2ca23a64 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Mon, 20 Sep 2021 23:23:29 +0200 Subject: [PATCH 6/9] Fix CI --- .github/workflows/ci.yml | 14 +++++++++----- Cargo.toml | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa5153b2..a6cb7ae1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,13 +63,17 @@ jobs: RUST_BACKTRACE: 1 strategy: matrix: - features: - - rspotify/cli,rspotify/env-file,rspotify/client-ureq,rspotify/ureq-rustls-tls,rspotify-http/client-ureq,rspotify-http/ureq-rustls-tls - - rspotify/cli,rspotify/env-file,rspotify/client-reqwest,rspotify/reqwest-rustls-tls,rspotify-http/client-reqwest,rspotify-http/reqwest-rustls-tls + # For testing both async and sync + directory: + - . + - rspotify-sync steps: - name: Checkout sources uses: actions/checkout@v2 + - name: Change directory + run: cd ${{ matrix.directory }} + - name: Install stable toolchain uses: actions-rs/toolchain@v1 with: @@ -82,10 +86,10 @@ jobs: uses: actions-rs/cargo@v1 with: command: clippy - args: -p rspotify -p rspotify-http -p rspotify-model -p rspotify-macros --no-default-features --features=${{ matrix.features }} -- -D warnings + args: --workspace --all-features -- -D warnings - name: Run cargo test uses: actions-rs/cargo@v1 with: command: test - args: -p rspotify -p rspotify-http -p rspotify-model -p rspotify-macros --no-default-features --features=${{ matrix.features }} + args: --workspace --all-features diff --git a/Cargo.toml b/Cargo.toml index 5e3d4a91..f40e7047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,9 @@ members = [ "rspotify-http" ] exclude = [ + # The synchronous crate must not be in the same workspace so that commands + # like `--workspace` don't enable both async and sync and thus fail due to + # conflicts. "rspotify-sync", "examples/webapp" ] From f6efc0fbf53c1eeb5d6a8c3fa0e287422868012b Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Mon, 20 Sep 2021 23:33:46 +0200 Subject: [PATCH 7/9] Fix warnings --- Cargo.toml | 13 ++++++------- rspotify-http/Cargo.toml | 2 -- rspotify-http/src/lib.rs | 4 ++-- rspotify-sync/Cargo.toml | 5 ++--- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f40e7047..a9f30cf2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,14 +33,14 @@ resolver = "2" [dependencies] rspotify-macros = { path = "rspotify-macros", version = "0.10.0" } rspotify-model = { path = "rspotify-model", version = "0.10.0" } -rspotify-http = { path = "rspotify-http", version = "0.10.0", default-features = false } +rspotify-http = { path = "rspotify-http", version = "0.10.0" } -async-stream = { version = "0.3.2", optional = true } -async-trait = { version = "0.1.51", optional = true } +async-stream = { version = "0.3.2" } +async-trait = { version = "0.1.51" } base64 = "0.13.0" chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } dotenv = { version = "0.15.0", optional = true } -futures = { version = "0.3.17", optional = true } +futures = { version = "0.3.17" } getrandom = "0.2.3" log = "0.4.14" maybe-async = "0.2.6" @@ -73,11 +73,10 @@ reqwest-native-tls = ["rspotify-http/reqwest-native-tls"] reqwest-native-tls-vendored = ["rspotify-http/reqwest-native-tls-vendored"] # Internal features for checking async or sync compilation -__async = ["futures", "async-stream", "async-trait"] +__async = [] [package.metadata.docs.rs] -# Documenting the CLI methods, and working links for `dotenv` -features = ["cli", "env-file"] +all-features = true [[example]] name = "client_creds" diff --git a/rspotify-http/Cargo.toml b/rspotify-http/Cargo.toml index c7952eb1..bcd71360 100644 --- a/rspotify-http/Cargo.toml +++ b/rspotify-http/Cargo.toml @@ -29,8 +29,6 @@ reqwest = { version = "0.11.4", default-features = false, features = ["json", "s ureq = { version = "2.2.0", default-features = false, features = ["json", "cookies"], optional = true } [features] -default = ["client-reqwest", "reqwest-default-tls"] - # Available clients. By default they don't include a TLS so that it can be # configured. client-ureq = ["ureq", "__sync"] diff --git a/rspotify-http/src/lib.rs b/rspotify-http/src/lib.rs index 4e29a8bd..68e7613d 100644 --- a/rspotify-http/src/lib.rs +++ b/rspotify-http/src/lib.rs @@ -8,12 +8,12 @@ mod common; #[cfg(feature = "client-reqwest")] -mod reqwest; +pub mod reqwest; #[cfg(feature = "client-reqwest")] pub use self::reqwest::ReqwestClient; #[cfg(feature = "client-ureq")] -mod ureq; +pub mod ureq; #[cfg(feature = "client-ureq")] pub use self::ureq::UreqClient; diff --git a/rspotify-sync/Cargo.toml b/rspotify-sync/Cargo.toml index 8fc9dd55..ad0f2b2c 100644 --- a/rspotify-sync/Cargo.toml +++ b/rspotify-sync/Cargo.toml @@ -19,7 +19,7 @@ path = "../src/lib.rs" [dependencies] rspotify-macros = { path = "../rspotify-macros", version = "0.10.0" } rspotify-model = { path = "../rspotify-model", version = "0.10.0" } -rspotify-http = { path = "../rspotify-http", version = "0.10.0", default-features = false } +rspotify-http = { path = "../rspotify-http", version = "0.10.0" } base64 = "0.13.0" chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } @@ -54,8 +54,7 @@ ureq-rustls-tls = ["rspotify-http/ureq-rustls-tls"] __sync = ["maybe-async/is_sync"] [package.metadata.docs.rs] -# Documenting the CLI methods, and working links for `dotenv` -features = ["cli", "env-file"] +all-features = true [[example]] name = "pagination_sync" From eb75b6c7fe328d466c10c4bfe05aa6092c8738b8 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Tue, 21 Sep 2021 14:16:19 +0200 Subject: [PATCH 8/9] Move rspotify-http into mod to fix last warnings --- Cargo.toml | 15 ++++--- rspotify-http/Cargo.toml | 47 --------------------- rspotify-sync/Cargo.toml | 8 ++-- {rspotify-http/src => src/http}/common.rs | 0 rspotify-http/src/lib.rs => src/http/mod.rs | 6 ++- {rspotify-http/src => src/http}/reqwest.rs | 2 +- {rspotify-http/src => src/http}/ureq.rs | 2 +- src/lib.rs | 2 +- 8 files changed, 20 insertions(+), 62 deletions(-) delete mode 100644 rspotify-http/Cargo.toml rename {rspotify-http/src => src/http}/common.rs (100%) rename rspotify-http/src/lib.rs => src/http/mod.rs (78%) rename {rspotify-http/src => src/http}/reqwest.rs (98%) rename {rspotify-http/src => src/http}/ureq.rs (97%) diff --git a/Cargo.toml b/Cargo.toml index a9f30cf2..ea6ff7c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ edition = "2018" members = [ "rspotify-macros", "rspotify-model", - "rspotify-http" ] exclude = [ # The synchronous crate must not be in the same workspace so that commands @@ -33,7 +32,6 @@ resolver = "2" [dependencies] rspotify-macros = { path = "rspotify-macros", version = "0.10.0" } rspotify-model = { path = "rspotify-model", version = "0.10.0" } -rspotify-http = { path = "rspotify-http", version = "0.10.0" } async-stream = { version = "0.3.2" } async-trait = { version = "0.1.51" } @@ -50,6 +48,9 @@ thiserror = "1.0.29" url = "2.2.2" webbrowser = { version = "0.5.5", optional = true } +# Supported clients +reqwest = { version = "0.11.4", default-features = false, features = ["json", "socks"], optional = true } + [dev-dependencies] env_logger = { version = "0.9.0", default-features = false } tokio = { version = "1.11.0", features = ["rt-multi-thread", "macros"] } @@ -64,13 +65,13 @@ env-file = ["dotenv"] ### HTTP ### # Only asynchronous clients are listed here. -client-reqwest = ["rspotify-http/client-reqwest", "__async"] +client-reqwest = ["reqwest", "__async"] # Passing the TLS features to reqwest. -reqwest-default-tls = ["rspotify-http/reqwest-default-tls"] -reqwest-rustls-tls = ["rspotify-http/reqwest-rustls-tls"] -reqwest-native-tls = ["rspotify-http/reqwest-native-tls"] -reqwest-native-tls-vendored = ["rspotify-http/reqwest-native-tls-vendored"] +reqwest-default-tls = ["reqwest/default-tls"] +reqwest-rustls-tls = ["reqwest/rustls-tls"] +reqwest-native-tls = ["reqwest/native-tls"] +reqwest-native-tls-vendored = ["reqwest/native-tls-vendored"] # Internal features for checking async or sync compilation __async = [] diff --git a/rspotify-http/Cargo.toml b/rspotify-http/Cargo.toml deleted file mode 100644 index bcd71360..00000000 --- a/rspotify-http/Cargo.toml +++ /dev/null @@ -1,47 +0,0 @@ -[package] -authors = [ - "Ramsay Leung ", - "Mario Ortiz Manero " -] -name = "rspotify-http" -version = "0.10.0" -license = "MIT" -readme = "README.md" -description = "HTTP compatibility layer for Rspotify" -homepage = "https://github.com/ramsayleung/rspotify" -repository = "https://github.com/ramsayleung/rspotify" -keywords = ["spotify", "api"] -edition = "2018" - -[dependencies] -rspotify-model = { path = "../rspotify-model", version = "0.10.0" } - -# Temporary until https://github.com/rust-lang/rfcs/issues/2739, for -# `maybe_async`. -async-trait = { version = "0.1.51", optional = true } -log = "0.4.14" -maybe-async = "0.2.6" -serde_json = "1.0.67" -thiserror = "1.0.29" - -# Supported clients -reqwest = { version = "0.11.4", default-features = false, features = ["json", "socks"], optional = true } -ureq = { version = "2.2.0", default-features = false, features = ["json", "cookies"], optional = true } - -[features] -# Available clients. By default they don't include a TLS so that it can be -# configured. -client-ureq = ["ureq", "__sync"] -client-reqwest = ["reqwest", "__async"] - -# Passing the TLS features to reqwest. -reqwest-default-tls = ["reqwest/default-tls"] -reqwest-rustls-tls = ["reqwest/rustls-tls"] -reqwest-native-tls = ["reqwest/native-tls"] -reqwest-native-tls-vendored = ["reqwest/native-tls-vendored"] -# Same for ureq. -ureq-rustls-tls = ["ureq/tls"] - -# Internal features for checking async or sync compilation -__async = ["async-trait"] -__sync = ["maybe-async/is_sync"] diff --git a/rspotify-sync/Cargo.toml b/rspotify-sync/Cargo.toml index ad0f2b2c..10229361 100644 --- a/rspotify-sync/Cargo.toml +++ b/rspotify-sync/Cargo.toml @@ -19,7 +19,6 @@ path = "../src/lib.rs" [dependencies] rspotify-macros = { path = "../rspotify-macros", version = "0.10.0" } rspotify-model = { path = "../rspotify-model", version = "0.10.0" } -rspotify-http = { path = "../rspotify-http", version = "0.10.0" } base64 = "0.13.0" chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } @@ -33,6 +32,9 @@ thiserror = "1.0.29" url = "2.2.2" webbrowser = { version = "0.5.5", optional = true } +# Supported clients +ureq = { version = "2.2.0", default-features = false, features = ["json", "cookies"], optional = true } + [dev-dependencies] env_logger = { version = "0.9.0", default-features = false } @@ -45,10 +47,10 @@ env-file = ["dotenv"] ### HTTP ### # Only synchronous clients are listed here. -client-ureq = ["rspotify-http/client-ureq", "__sync"] +client-ureq = ["ureq", "__sync"] # Passing the TLS features to ureq. -ureq-rustls-tls = ["rspotify-http/ureq-rustls-tls"] +ureq-rustls-tls = ["ureq/rustls"] # Internal features for checking async or sync compilation __sync = ["maybe-async/is_sync"] diff --git a/rspotify-http/src/common.rs b/src/http/common.rs similarity index 100% rename from rspotify-http/src/common.rs rename to src/http/common.rs diff --git a/rspotify-http/src/lib.rs b/src/http/mod.rs similarity index 78% rename from rspotify-http/src/lib.rs rename to src/http/mod.rs index 68e7613d..bf6b3382 100644 --- a/rspotify-http/src/lib.rs +++ b/src/http/mod.rs @@ -5,7 +5,11 @@ // This way only the compile error below gets shown instead of a whole list of // confusing errors.. +// If no client is configured the crate is empty to avoid compilation errors +#[cfg(any(feature = "__async", feature = "__sync"))] mod common; +#[cfg(any(feature = "__async", feature = "__sync"))] +pub use common::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; #[cfg(feature = "client-reqwest")] pub mod reqwest; @@ -16,5 +20,3 @@ pub use self::reqwest::ReqwestClient; pub mod ureq; #[cfg(feature = "client-ureq")] pub use self::ureq::UreqClient; - -pub use common::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; diff --git a/rspotify-http/src/reqwest.rs b/src/http/reqwest.rs similarity index 98% rename from rspotify-http/src/reqwest.rs rename to src/http/reqwest.rs index 40b46fe7..808e3962 100644 --- a/rspotify-http/src/reqwest.rs +++ b/src/http/reqwest.rs @@ -1,7 +1,7 @@ //! The client implementation for the reqwest HTTP client, which is async by //! default. -use crate::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; +use crate::http::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; use std::convert::TryInto; diff --git a/rspotify-http/src/ureq.rs b/src/http/ureq.rs similarity index 97% rename from rspotify-http/src/ureq.rs rename to src/http/ureq.rs index c8e3ac16..8aa5e6f9 100644 --- a/rspotify-http/src/ureq.rs +++ b/src/http/ureq.rs @@ -1,6 +1,6 @@ //! The client implementation for the ureq HTTP client, which is blocking. -use crate::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; +use crate::http::{BaseHttpClient, Form, Headers, HttpError, HttpResult, Query}; use maybe_async::sync_impl; use serde_json::Value; diff --git a/src/lib.rs b/src/lib.rs index f921a1dc..e24d4e47 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,9 +125,9 @@ pub mod auth_code; pub mod auth_code_pkce; pub mod client_creds; pub mod clients; +pub mod http; // Subcrate re-exports -pub use rspotify_http as http; pub use rspotify_macros as macros; pub use rspotify_model as model; // Top-level re-exports From 90a6d9e9b8f37fc2983ef328ccb0bfe55b5bf189 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Tue, 21 Sep 2021 14:25:41 +0200 Subject: [PATCH 9/9] Bump versions --- Cargo.toml | 8 ++++---- rspotify-macros/Cargo.toml | 2 +- rspotify-model/Cargo.toml | 2 +- rspotify-sync/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ea6ff7c2..de853e0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,17 +33,17 @@ resolver = "2" rspotify-macros = { path = "rspotify-macros", version = "0.10.0" } rspotify-model = { path = "rspotify-model", version = "0.10.0" } -async-stream = { version = "0.3.2" } -async-trait = { version = "0.1.51" } +async-stream = "0.3.2" +async-trait = "0.1.51" base64 = "0.13.0" chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } dotenv = { version = "0.15.0", optional = true } -futures = { version = "0.3.17" } +futures = "0.3.17" getrandom = "0.2.3" log = "0.4.14" maybe-async = "0.2.6" serde = { version = "1.0.130", default-features = false } -serde_json = "1.0.67" +serde_json = "1.0.68" thiserror = "1.0.29" url = "2.2.2" webbrowser = { version = "0.5.5", optional = true } diff --git a/rspotify-macros/Cargo.toml b/rspotify-macros/Cargo.toml index 9492ffa7..fb9c364e 100644 --- a/rspotify-macros/Cargo.toml +++ b/rspotify-macros/Cargo.toml @@ -14,4 +14,4 @@ keywords = ["spotify", "api", "rspotify"] edition = "2018" [dev-dependencies] -serde_json = "1.0.67" +serde_json = "1.0.68" diff --git a/rspotify-model/Cargo.toml b/rspotify-model/Cargo.toml index 3f2cf6e9..b1d629f3 100644 --- a/rspotify-model/Cargo.toml +++ b/rspotify-model/Cargo.toml @@ -16,7 +16,7 @@ edition = "2018" [dependencies] chrono = { version = "0.4.19", features = ["serde", "rustc-serialize"] } serde = { version = "1.0.130", features = ["derive"] } -serde_json = "1.0.67" +serde_json = "1.0.68" strum = { version = "0.21.0", features = ["derive"] } thiserror = "1.0.29" diff --git a/rspotify-sync/Cargo.toml b/rspotify-sync/Cargo.toml index 10229361..45ee5c76 100644 --- a/rspotify-sync/Cargo.toml +++ b/rspotify-sync/Cargo.toml @@ -27,7 +27,7 @@ getrandom = "0.2.3" log = "0.4.14" maybe-async = "0.2.6" serde = { version = "1.0.130", default-features = false } -serde_json = "1.0.67" +serde_json = "1.0.68" thiserror = "1.0.29" url = "2.2.2" webbrowser = { version = "0.5.5", optional = true }