1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use serde;
use std::marker::PhantomData;
use {Transport, Error, ErrorKind};
pub struct Action<'a, T> where T: 'a + serde::de::Deserialize {
transport: &'a Transport,
resource: Resource,
query: Vec<Query>,
response_type: PhantomData<&'a T>
}
impl<'a, T> Action<'a, T> where T: 'a + serde::de::Deserialize {
#[doc(hidden)]
pub fn new(transport: &'a Transport, resource: Resource) -> Self {
Action {
transport: transport,
resource: resource,
query: Vec::new(),
response_type: PhantomData,
}
}
pub fn set(mut self, query: Query) -> Self {
self.query.push(query);
self
}
pub fn user_id(self, v: u32) -> Self { self.set(Query::UserId(v)) }
pub fn offset(self, v: u32) -> Self { self.set(Query::Offset(v)) }
pub fn limit(self, v: u32) -> Self { self.set(Query::Limit(v)) }
pub fn album_id(self, v: u32) -> Self { self.set(Query::AlbumId(v)) }
pub fn artist_id(self, v: u32) -> Self { self.set(Query::ArtistId(v)) }
pub fn track_id(self, v: u32) -> Self { self.set(Query::TrackId(v)) }
pub fn album_name(self, v: &str) -> Self { self.set(Query::AlbumName(v.into())) }
pub fn artist_name(self, v: &str) -> Self { self.set(Query::ArtistName(v.into())) }
pub fn track_name(self, v: &str) -> Self { self.set(Query::TrackName(v.into())) }
pub fn name_search(self, v: &str) -> Self { self.set(Query::NameSearch(v.into())) }
pub fn featured(self, v: bool) -> Self { self.set(Query::Featured(v)) }
pub fn run(self) -> Result<Vec<T>, Error> {
use Resource::*;
use Query::*;
let path = match self.resource {
GetAlbums => "albums",
GetUsersAlbums => "users/albums",
GetArtists => "artists",
GetUsersArtists => "users/artists",
Resource::GetTracks => "tracks",
GetUsersTracks => "users/tracks",
};
let mut query_pairs: Vec<(&str, String)> = Vec::new();
for q in self.query.iter() {
query_pairs.push(match q {
&UserId(ref v) => match self.resource {
GetUsersAlbums | GetUsersArtists | GetUsersTracks => ("id", v.to_string()),
_ => return Err(Error::Client(ErrorKind::InvalidQuery)),
},
&Offset(ref v) => ("offset", v.to_string()),
&Limit(ref v) => ("limit", v.to_string()),
&AlbumId(ref v) => match self.resource {
GetAlbums => ("id", v.to_string()),
_ => ("album_id", v.to_string()),
},
&ArtistId(ref v) => match self.resource {
GetArtists => ("id", v.to_string()),
_ => ("artist_id", v.to_string()),
},
&TrackId(ref v) => match self.resource {
GetTracks => ("id", v.to_string()),
_ => ("track_id", v.to_string()),
},
&AlbumName(ref v) => match self.resource {
GetAlbums => ("name", v.clone()),
_ => ("album_name", v.clone()),
},
&ArtistName(ref v) => match self.resource {
GetArtists => ("name", v.clone()),
_ => ("artist_name", v.clone()),
},
&TrackName(ref v) => match self.resource {
GetTracks => ("name", v.clone()),
_ => ("track_name", v.clone()),
},
&NameSearch(ref v) => ("namesearch", v.clone()),
&Featured(ref v) => ("featured", v.to_string()),
});
}
Ok(self.transport.get(path, query_pairs)?.results)
}
pub fn unwrap(self) -> Vec<T> {
self.run().unwrap()
}
}
pub enum Resource {
GetAlbums,
GetUsersAlbums,
GetArtists,
GetUsersArtists,
GetTracks,
GetUsersTracks,
}
pub enum Query {
UserId(u32),
Offset(u32),
Limit(u32),
AlbumId(u32),
ArtistId(u32),
TrackId(u32),
AlbumName(String),
ArtistName(String),
TrackName(String),
NameSearch(String),
Featured(bool),
}