lastfm_edit/edit.rs
1/// Represents a scrobble edit operation.
2///
3/// This structure contains all the information needed to edit a specific scrobble
4/// on Last.fm, including both the original and new metadata values.
5///
6/// # Examples
7///
8/// ```rust
9/// use lastfm_edit::ScrobbleEdit;
10///
11/// // Create an edit to fix a track name
12/// let edit = ScrobbleEdit::from_track_info(
13/// "Paranoid Andriod", // original (misspelled)
14/// "OK Computer",
15/// "Radiohead",
16/// 1640995200
17/// )
18/// .with_track_name("Paranoid Android"); // corrected
19///
20/// // Create an edit to change artist name
21/// let edit = ScrobbleEdit::from_track_info(
22/// "Creep",
23/// "Pablo Honey",
24/// "Radio Head", // original (wrong)
25/// 1640995200
26/// )
27/// .with_artist_name("Radiohead") // corrected
28/// .with_edit_all(true); // update all instances
29/// ```
30#[derive(Debug, Clone)]
31pub struct ScrobbleEdit {
32 /// Original track name as it appears in the scrobble
33 /// If None, the client will attempt to look up the complete original metadata
34 pub track_name_original: Option<String>,
35 /// Original album name as it appears in the scrobble
36 /// If None, the client will attempt to look up the complete original metadata
37 pub album_name_original: Option<String>,
38 /// Original artist name as it appears in the scrobble
39 /// If None, the client will attempt to look up the complete original metadata
40 pub artist_name_original: Option<String>,
41 /// Original album artist name as it appears in the scrobble
42 /// If None, the client will attempt to look up the complete original metadata
43 pub album_artist_name_original: Option<String>,
44
45 /// New track name to set
46 pub track_name: String,
47 /// New album name to set
48 pub album_name: String,
49 /// New artist name to set
50 pub artist_name: String,
51 /// New album artist name to set
52 pub album_artist_name: String,
53
54 /// Unix timestamp of the scrobble to edit
55 ///
56 /// This identifies the specific scrobble instance to modify.
57 pub timestamp: u64,
58 /// Whether to edit all instances or just this specific scrobble
59 ///
60 /// When `true`, Last.fm will update all scrobbles with matching metadata.
61 /// When `false`, only this specific scrobble (identified by timestamp) is updated.
62 pub edit_all: bool,
63}
64
65/// Response from a scrobble edit operation.
66///
67/// This structure contains the result of attempting to edit a scrobble,
68/// including success status and any error messages.
69///
70/// # Examples
71///
72/// ```rust
73/// use lastfm_edit::EditResponse;
74///
75/// let response = EditResponse {
76/// success: true,
77/// message: Some("Track name updated successfully".to_string()),
78/// };
79///
80/// if response.success {
81/// println!("Edit succeeded: {}", response.message.unwrap_or_default());
82/// } else {
83/// eprintln!("Edit failed: {}", response.message.unwrap_or_default());
84/// }
85/// ```
86#[derive(Debug)]
87pub struct EditResponse {
88 /// Whether the edit operation was successful
89 pub success: bool,
90 /// Optional message describing the result or any errors
91 pub message: Option<String>,
92}
93
94impl ScrobbleEdit {
95 /// Create a new [`ScrobbleEdit`] with all required fields.
96 ///
97 /// This is the most general constructor that allows setting all fields.
98 /// For convenience, consider using [`from_track_info`](Self::from_track_info) instead.
99 ///
100 /// # Arguments
101 ///
102 /// * `track_name_original` - The current track name in the scrobble
103 /// * `album_name_original` - The current album name in the scrobble
104 /// * `artist_name_original` - The current artist name in the scrobble
105 /// * `album_artist_name_original` - The current album artist name in the scrobble
106 /// * `track_name` - The new track name to set
107 /// * `album_name` - The new album name to set
108 /// * `artist_name` - The new artist name to set
109 /// * `album_artist_name` - The new album artist name to set
110 /// * `timestamp` - Unix timestamp identifying the scrobble
111 /// * `edit_all` - Whether to edit all matching scrobbles or just this one
112 #[allow(clippy::too_many_arguments)]
113 pub fn new(
114 track_name_original: Option<String>,
115 album_name_original: Option<String>,
116 artist_name_original: Option<String>,
117 album_artist_name_original: Option<String>,
118 track_name: String,
119 album_name: String,
120 artist_name: String,
121 album_artist_name: String,
122 timestamp: u64,
123 edit_all: bool,
124 ) -> Self {
125 Self {
126 track_name_original,
127 album_name_original,
128 artist_name_original,
129 album_artist_name_original,
130 track_name,
131 album_name,
132 artist_name,
133 album_artist_name,
134 timestamp,
135 edit_all,
136 }
137 }
138
139 /// Create an edit request from track information (convenience constructor).
140 ///
141 /// This constructor creates a [`ScrobbleEdit`] with the new values initially
142 /// set to the same as the original values. Use the builder methods like
143 /// [`with_track_name`](Self::with_track_name) to specify what should be changed.
144 ///
145 /// # Arguments
146 ///
147 /// * `original_track` - The current track name
148 /// * `original_album` - The current album name
149 /// * `original_artist` - The current artist name
150 /// * `timestamp` - Unix timestamp identifying the scrobble
151 ///
152 /// # Examples
153 ///
154 /// ```rust
155 /// use lastfm_edit::ScrobbleEdit;
156 ///
157 /// let edit = ScrobbleEdit::from_track_info(
158 /// "Highway to Hell",
159 /// "Highway to Hell",
160 /// "AC/DC",
161 /// 1640995200
162 /// )
163 /// .with_track_name("Highway to Hell (Remastered)");
164 /// ```
165 pub fn from_track_info(
166 original_track: &str,
167 original_album: &str,
168 original_artist: &str,
169 timestamp: u64,
170 ) -> Self {
171 Self::new(
172 Some(original_track.to_string()),
173 Some(original_album.to_string()),
174 Some(original_artist.to_string()),
175 Some(original_artist.to_string()), // album_artist defaults to artist
176 original_track.to_string(),
177 original_album.to_string(),
178 original_artist.to_string(),
179 original_artist.to_string(), // album_artist defaults to artist
180 timestamp,
181 false, // edit_all defaults to false
182 )
183 }
184
185 /// Set the new track name.
186 ///
187 /// # Examples
188 ///
189 /// ```rust
190 /// # use lastfm_edit::ScrobbleEdit;
191 /// let edit = ScrobbleEdit::from_track_info("Wrong Name", "Album", "Artist", 1640995200)
192 /// .with_track_name("Correct Name");
193 /// ```
194 pub fn with_track_name(mut self, track_name: &str) -> Self {
195 self.track_name = track_name.to_string();
196 self
197 }
198
199 /// Set the new album name.
200 ///
201 /// # Examples
202 ///
203 /// ```rust
204 /// # use lastfm_edit::ScrobbleEdit;
205 /// let edit = ScrobbleEdit::from_track_info("Track", "Wrong Album", "Artist", 1640995200)
206 /// .with_album_name("Correct Album");
207 /// ```
208 pub fn with_album_name(mut self, album_name: &str) -> Self {
209 self.album_name = album_name.to_string();
210 self
211 }
212
213 /// Set the new artist name.
214 ///
215 /// This also sets the album artist name to the same value.
216 ///
217 /// # Examples
218 ///
219 /// ```rust
220 /// # use lastfm_edit::ScrobbleEdit;
221 /// let edit = ScrobbleEdit::from_track_info("Track", "Album", "Wrong Artist", 1640995200)
222 /// .with_artist_name("Correct Artist");
223 /// ```
224 pub fn with_artist_name(mut self, artist_name: &str) -> Self {
225 self.artist_name = artist_name.to_string();
226 self.album_artist_name = artist_name.to_string();
227 self
228 }
229
230 /// Set whether to edit all instances of this track.
231 ///
232 /// When `true`, Last.fm will update all scrobbles with the same metadata.
233 /// When `false` (default), only the specific scrobble is updated.
234 ///
235 /// # Examples
236 ///
237 /// ```rust
238 /// # use lastfm_edit::ScrobbleEdit;
239 /// let edit = ScrobbleEdit::from_track_info("Track", "Album", "Artist", 1640995200)
240 /// .with_track_name("New Name")
241 /// .with_edit_all(true); // Update all instances
242 /// ```
243 pub fn with_edit_all(mut self, edit_all: bool) -> Self {
244 self.edit_all = edit_all;
245 self
246 }
247
248 /// Create an edit request with minimal information, letting the client look up missing metadata.
249 ///
250 /// This constructor is useful when you only know some of the original metadata and want
251 /// the client to automatically fill in missing information by looking up the scrobble.
252 ///
253 /// # Arguments
254 ///
255 /// * `track_name` - The new track name to set
256 /// * `artist_name` - The new artist name to set
257 /// * `album_name` - The new album name to set
258 /// * `timestamp` - Unix timestamp identifying the scrobble
259 ///
260 /// # Examples
261 ///
262 /// ```rust
263 /// use lastfm_edit::ScrobbleEdit;
264 ///
265 /// // Create an edit where the client will look up original metadata
266 /// let edit = ScrobbleEdit::with_minimal_info(
267 /// "Corrected Track Name",
268 /// "Corrected Artist",
269 /// "Corrected Album",
270 /// 1640995200
271 /// );
272 /// ```
273 pub fn with_minimal_info(
274 track_name: &str,
275 artist_name: &str,
276 album_name: &str,
277 timestamp: u64,
278 ) -> Self {
279 Self::new(
280 None, // Client will look up original track name
281 None, // Client will look up original album name
282 None, // Client will look up original artist name
283 None, // Client will look up original album artist name
284 track_name.to_string(),
285 album_name.to_string(),
286 artist_name.to_string(),
287 artist_name.to_string(), // album_artist defaults to artist
288 timestamp,
289 false,
290 )
291 }
292}