1use query::Query;
2use {Album, Artist, Client, Error, Result, Song};
3
4pub trait Annotatable {
6 fn star(&self, client: &Client) -> Result<()>;
8
9 fn unstar(&self, client: &Client) -> Result<()>;
11
12 fn set_rating(&self, client: &Client, rating: u8) -> Result<()>;
14
15 fn scrobble<'a, B, T>(&self, client: &Client, time: T, now_playing: B) -> Result<()>
31 where
32 B: Into<Option<bool>>,
33 T: Into<Option<&'a str>>;
34}
35
36impl Annotatable for Artist {
37 fn star(&self, client: &Client) -> Result<()> {
38 client.get("star", Query::with("artistId", self.id))?;
39 Ok(())
40 }
41
42 fn unstar(&self, client: &Client) -> Result<()> {
43 client.get("unstar", Query::with("artistId", self.id))?;
44 Ok(())
45 }
46
47 fn set_rating(&self, client: &Client, rating: u8) -> Result<()> {
48 if rating > 5 {
49 return Err(Error::Other("rating must be between 0 and 5 inclusive"));
50 }
51
52 let args = Query::with("id", self.id).arg("rating", rating).build();
53 client.get("setRating", args)?;
54 Ok(())
55 }
56
57 fn scrobble<'a, B, T>(&self, client: &Client, time: T, now_playing: B) -> Result<()>
58 where
59 B: Into<Option<bool>>,
60 T: Into<Option<&'a str>>,
61 {
62 let args = Query::with("id", self.id)
63 .arg("time", time.into())
64 .arg("submission", now_playing.into().map(|b| !b))
65 .build();
66 client.get("scrobble", args)?;
67 Ok(())
68 }
69}
70
71impl Annotatable for Album {
72 fn star(&self, client: &Client) -> Result<()> {
73 client.get("star", Query::with("albumId", self.id))?;
74 Ok(())
75 }
76
77 fn unstar(&self, client: &Client) -> Result<()> {
78 client.get("unstar", Query::with("albumId", self.id))?;
79 Ok(())
80 }
81
82 fn set_rating(&self, client: &Client, rating: u8) -> Result<()> {
83 if rating > 5 {
84 return Err(Error::Other("rating must be between 0 and 5 inclusive"));
85 }
86
87 let args = Query::with("id", self.id).arg("rating", rating).build();
88 client.get("setRating", args)?;
89 Ok(())
90 }
91
92 fn scrobble<'a, B, T>(&self, client: &Client, time: T, now_playing: B) -> Result<()>
93 where
94 B: Into<Option<bool>>,
95 T: Into<Option<&'a str>>,
96 {
97 let args = Query::with("id", self.id)
98 .arg("time", time.into())
99 .arg("submission", now_playing.into().map(|b| !b))
100 .build();
101 client.get("scrobble", args)?;
102 Ok(())
103 }
104}
105
106impl Annotatable for Song {
107 fn star(&self, client: &Client) -> Result<()> {
108 client.get("star", Query::with("id", self.id))?;
109 Ok(())
110 }
111
112 fn unstar(&self, client: &Client) -> Result<()> {
113 client.get("unstar", Query::with("id", self.id))?;
114 Ok(())
115 }
116
117 fn set_rating(&self, client: &Client, rating: u8) -> Result<()> {
118 if rating > 5 {
119 return Err(Error::Other("rating must be between 0 and 5 inclusive"));
120 }
121
122 let args = Query::with("id", self.id).arg("rating", rating).build();
123 client.get("setRating", args)?;
124 Ok(())
125 }
126
127 fn scrobble<'a, B, T>(&self, client: &Client, time: T, now_playing: B) -> Result<()>
128 where
129 B: Into<Option<bool>>,
130 T: Into<Option<&'a str>>,
131 {
132 let args = Query::with("id", self.id)
133 .arg("time", time.into())
134 .arg("submission", now_playing.into().map(|b| !b))
135 .build();
136 client.get("scrobble", args)?;
137 Ok(())
138 }
139}