Skip to content

Commit

Permalink
Merge pull request #497 from jakin010/master
Browse files Browse the repository at this point in the history
Added support for multiple search and added some tests
  • Loading branch information
ramsayleung authored Sep 30, 2024
2 parents d91d367 + 48c081d commit c84d7bd
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

**Bugfixes**
- ([#494](https://github.com/ramsayleung/rspotify/pull/494)) Fix endless sequential pagination problem.

**New features**
- ([#496](https://github.com/ramsayleung/rspotify/pull/497)) Add support for searching multiple types


## 0.13.3 (2024.08.24)
**New features**
Expand Down
11 changes: 11 additions & 0 deletions rspotify-model/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ pub enum SearchResult {
#[serde(rename = "episodes")]
Episodes(Page<SimplifiedEpisode>),
}

/// Search result of any multiple kinds
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct SearchMultipleResult {
pub playlists: Option<Page<SimplifiedPlaylist>>,
pub albums: Option<Page<SimplifiedAlbum>>,
pub artists: Option<Page<FullArtist>>,
pub tracks: Option<Page<FullTrack>>,
pub shows: Option<Page<SimplifiedShow>>,
pub episodes: Option<Page<SimplifiedEpisode>>,
}
53 changes: 52 additions & 1 deletion src/clients/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ where
/// - market - An ISO 3166-1 alpha-2 country code or the string from_token.
/// - include_external: Optional.Possible values: audio. If
/// include_external=audio is specified the response will include any
/// relevant audio content that is hosted externally.
/// relevant audio content that is hosted externally.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/search)
async fn search(
Expand All @@ -454,6 +454,57 @@ where
convert_result(&result)
}

/// Search for multiple an Item. Get Spotify catalog information about artists,
/// albums, tracks or playlists that match a keyword string.
///
/// According to Spotify's doc, if you don't specify a country in the
/// request and your spotify account doesn't set the country, the content
/// might be unavailable for you:
/// > If a valid user access token is specified in the request header,
/// > the country associated with the user account will take priority over this parameter.
/// > Note: If neither market or user country are provided, the content is considered unavailable for the client.
/// > Users can view the country that is associated with their account in the [account settings](https://developer.spotify.com/documentation/web-api/reference/search).
///
/// Parameters:
/// - q - the search query
/// - limit - the number of items to return
/// - offset - the index of the first item to return
/// - type - the type of item to return. Multiple of 'artist', 'album', 'track',
/// 'playlist', 'show' or 'episode'
/// - market - An ISO 3166-1 alpha-2 country code or the string from_token.
/// - include_external: Optional.Possible values: audio. If
/// include_external=audio is specified the response will include any
/// relevant audio content that is hosted externally.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/#/operations/search)
async fn search_multiple(
&self,
q: &str,
r#type: impl IntoIterator<Item = SearchType> + Send,
market: Option<Market>,
include_external: Option<IncludeExternal>,
limit: Option<u32>,
offset: Option<u32>,
) -> ClientResult<SearchMultipleResult> {
let limit = limit.map(|s| s.to_string());
let offset = offset.map(|s| s.to_string());
let mut _type = r#type
.into_iter()
.map(|x| Into::<&str>::into(x).to_string() + ",")
.collect::<String>();
let params = build_map([
("q", Some(q)),
("type", Some(_type.trim_end_matches(","))),
("market", market.map(Into::into)),
("include_external", include_external.map(Into::into)),
("limit", limit.as_deref()),
("offset", offset.as_deref()),
]);

let result = self.api_get("search", &params).await?;
convert_result(&result)
}

/// Get Spotify catalog information about an album's tracks.
///
/// Parameters:
Expand Down
36 changes: 36 additions & 0 deletions tests/test_with_credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rspotify::{

use maybe_async::maybe_async;

use rspotify_model::SearchType;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;

Expand Down Expand Up @@ -273,6 +274,41 @@ async fn test_fake_playlist() {
assert!(playlist.is_err());
}

#[maybe_async::test(
feature = "__sync",
async(all(feature = "__async", not(target_arch = "wasm32")), tokio::test),
async(all(feature = "__async", target_arch = "wasm32"), wasm_bindgen_test)
)]
async fn test_search_album() {
let query = "album:arrival artist:abba";
creds_client()
.await
.search(query, SearchType::Album, None, None, Some(10), Some(0))
.await
.unwrap();
}

#[maybe_async::test(
feature = "__sync",
async(all(feature = "__async", not(target_arch = "wasm32")), tokio::test),
async(all(feature = "__async", target_arch = "wasm32"), wasm_bindgen_test)
)]
async fn test_search_multiple_types() {
let query = "album:arrival artist:abba";
creds_client()
.await
.search_multiple(
query,
vec![SearchType::Artist, SearchType::Album],
None,
None,
Some(10),
Some(0),
)
.await
.unwrap();
}

pub mod test_pagination {
use super::*;

Expand Down

0 comments on commit c84d7bd

Please sign in to comment.