use data_structures::*;
use query::*;
use serde_json;
pub const ARTIST_ENDPOINT: &'static str = "/artists";
#[derive(Deserialize, Debug)]
pub struct ArtistReleases {
pub pagination: Pagination,
pub releases: Vec<Release>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Artist {
pub id: u32,
pub name: String,
pub resource_url: String,
pub tracks: Option<String>,
pub uri: Option<String>,
pub releases_url: Option<String>,
pub aliases: Option<Vec<Artist>>,
pub join: Option<String>,
pub role: Option<String>,
pub anv: Option<String>,
pub members: Option<Vec<Artist>>,
pub active: Option<bool>,
pub namevariations: Option<Vec<String>>,
pub urls: Option<Vec<String>>,
pub images: Option<Vec<Image>>,
pub profile: Option<String>,
pub data_quality: Option<DataQuality>,
pub realname: Option<String>,
}
impl Artist {
pub fn new(id: u32, name: String, resource_url: String) -> Artist {
Artist {
id: id,
name: name,
resource_url: resource_url,
tracks: None,
uri: None,
releases_url: None,
aliases: None,
join: None,
role: None,
anv: None,
members: None,
active: None,
namevariations: None,
urls: None,
images: None,
profile: None,
data_quality: None,
realname: None,
}
}
}
impl PartialEq for Artist {
fn eq(&self, other: &Artist) -> bool {
other.id == self.id
}
}
pub struct ArtistQueryBuilder {
id: u32,
api_endpoint: String,
user_agent: String,
key: Option<String>,
secret: Option<String>,
page: i16,
per_page: i16,
releases : bool
}
impl ArtistQueryBuilder {
pub fn new(id: u32,
api_endpoint: String,
user_agent: String,
key: Option<String>,
secret: Option<String>) -> ArtistQueryBuilder {
ArtistQueryBuilder {
id: id,
api_endpoint: api_endpoint,
user_agent: user_agent,
key: key,
secret: secret,
page : 1,
per_page : 50,
releases : false
}
}
pub fn get(self) -> Result<Artist, QueryError> {
let result: Result<String, QueryError> = self.perform_request();
if let Err(error) = result {
return Err(error);
} else {
let result_string = result.ok().unwrap();
let json = serde_json::from_str(&result_string);
if let Ok(artist) = json {
return Ok(artist);
} else {
return Err(QueryError::JsonDecodeError {
serde_err: json.err()
});
}
}
}
pub fn pagination(mut self, page: i16, per_page: i16) -> ArtistQueryBuilder {
self.page = page;
self.per_page = per_page;
self
}
pub fn get_releases(mut self) -> Result<ArtistReleases, QueryError> {
self.releases = true;
let result: Result<String, QueryError> = self.perform_request();
if let Err(error) = result {
return Err(error);
} else {
let result_string = result.ok().unwrap();
let json = serde_json::from_str(&result_string);
if let Ok(artist) = json {
return Ok(artist);
} else {
return Err(QueryError::JsonDecodeError {
serde_err: json.err()
});
}
}
}
}
impl QueryBuilder for ArtistQueryBuilder {
fn get_key(&self) -> Option<String> {
self.key.clone()
}
fn get_secret(&self) -> Option<String> {
self.secret.clone()
}
fn get_query_url(&self) -> String {
match self.releases {
false => format!("{}{}/{}", self.api_endpoint, ARTIST_ENDPOINT, self.id),
true => format!("{}{}/{}/releases?page={}&per_page={}", self.api_endpoint, ARTIST_ENDPOINT, self.id, self.page, self.per_page)
}
}
fn get_user_agent(&self) -> String {
self.user_agent.clone()
}
}
#[cfg(test)]
mod tests {
use discogs::*;
use data_structures::*;
use mockito::mock;
use serde_json;
use serde_json::to_string;
fn aqb(id: u32) -> ArtistQueryBuilder {
Discogs::new("USER_AGENT").artist(id)
}
#[test]
fn test_request_builder() {
let qb = aqb(789);
assert_eq!(qb.id, 789);
assert_eq!(qb.api_endpoint, API_URL.to_owned());
assert_eq!(qb.user_agent, "USER_AGENT".to_string());
assert!(qb.key.is_none());
assert!(qb.secret.is_none());
}
#[test]
fn test_artist_new() {
let artist = Artist::new(4567,
"name".to_string(),
"resource_url".to_string());
assert_eq!(artist.id, 4567);
assert_eq!(artist.name, "name".to_string());
assert_eq!(artist.resource_url, "resource_url".to_string());
}
#[test]
fn test_artist_eq() {
let artist = Artist::new(4567,
"name".to_string(),
"resource_url".to_string());
let artist2 = Artist::new(4567,
"adsh".to_string(),
"dasdas".to_string());
assert!(artist == artist2);
}
#[test]
fn test_perform_artist_request() {
mock("GET", "/artists/4567")
.with_status(200)
.with_header("content-type", "text/json")
.with_body(to_string(&json!({
"id": 4567,
"resource_url": "https://api.discogs.com/artists/4567",
"name": "Whirlpool Productions"
})).unwrap().as_str())
.create_for(|| {
let artist = Discogs::new("USER_AGENT")
.artist(4567)
.get()
.ok()
.unwrap();
assert_eq!(artist.id, 4567);
assert_eq!(artist.resource_url, "https://api.discogs.com/artists/4567".to_string());
assert_eq!(artist.name, "Whirlpool Productions".to_string());
});
}
#[test]
fn test_perform_artist_releases_request() {
mock("GET", "/artists/4567/releases?page=1&per_page=2")
.with_status(200)
.with_header("content-type", "text/json")
.with_body(to_string(&json!(
{
"pagination": {
"per_page": 2,
"items": 220,
"page": 1,
"urls": {
"last": "https://api.discogs.com/artists/4567/releases?per_page=2&page=110",
"next": "https://api.discogs.com/artists/4567/releases?per_page=2&page=2"
},
"pages": 110
},
"releases": [{
"status": "Accepted",
"thumb": "",
"title": "Fly High",
"format": "12\"",
"label": "5th & Madison",
"role": "Main",
"year": 1992,
"resource_url": "https://api.discogs.com/releases/843401",
"artist": "Whirlpool*",
"type": "release",
"id": 843401
}, {
"status": "Accepted",
"thumb": "",
"title": "Dream Team E.P.",
"format": "12\", EP",
"label": "Intense Recordings",
"role": "Main",
"year": 1993,
"resource_url": "https://api.discogs.com/releases/94983",
"artist": "T'N'I / Whirlpool Productions",
"type": "release",
"id": 94983
}]
}
)).unwrap().as_str())
.create_for(|| {
let mut releases = Discogs::new("USER_AGENT")
.artist(4567)
.pagination(1, 2)
.get_releases()
.ok()
.unwrap();
assert_eq!(releases.pagination.page,1);
assert_eq!(releases.pagination.per_page,2);
assert_eq!(releases.pagination.items,220);
assert_eq!(releases.pagination.pages,110);
assert_eq!(releases.releases.len(), 2);
assert_eq!(releases.releases[0].title, "Fly High");
assert_eq!(releases.releases[0].id, 843401);
assert_eq!(releases.releases[0].resource_url, "https://api.discogs.com/releases/843401");
assert_eq!(releases.releases[0].artist, Some(String::from("Whirlpool*")));
assert_eq!(releases.releases[0].label, Some(String::from("5th & Madison")));
});
}
}