lastfm_edit/discovery/
track_variations.rs1use super::common::filter_by_original_album_artist;
2use crate::{
3 AsyncDiscoveryIterator, ExactScrobbleEdit, LastFmEditClientImpl, Result, ScrobbleEdit,
4};
5use async_trait::async_trait;
6
7pub struct TrackVariationsDiscovery {
13 client: LastFmEditClientImpl,
14 edit: ScrobbleEdit,
15 track_name: String,
16 scrobbles_loaded: bool,
17 current_results: Vec<ExactScrobbleEdit>,
18 current_index: usize,
19}
20
21impl TrackVariationsDiscovery {
22 pub fn new(client: LastFmEditClientImpl, edit: ScrobbleEdit, track_name: String) -> Self {
23 Self {
24 client,
25 edit,
26 track_name,
27 scrobbles_loaded: false,
28 current_results: Vec::new(),
29 current_index: 0,
30 }
31 }
32}
33
34#[async_trait(?Send)]
35impl AsyncDiscoveryIterator<ExactScrobbleEdit> for TrackVariationsDiscovery {
36 async fn next(&mut self) -> Result<Option<ExactScrobbleEdit>> {
37 if self.current_index < self.current_results.len() {
39 let result = self.current_results[self.current_index].clone();
40 self.current_index += 1;
41 return Ok(Some(result));
42 }
43
44 if !self.scrobbles_loaded {
46 log::debug!(
47 "Getting scrobble data for track '{}' by '{}'",
48 self.track_name,
49 self.edit.artist_name_original
50 );
51
52 match self
53 .client
54 .load_edit_form_values_internal(&self.track_name, &self.edit.artist_name_original)
55 .await
56 {
57 Ok(track_scrobbles) => {
58 let mut modified_edits = Vec::new();
60 for scrobble in track_scrobbles {
61 let mut modified_edit = scrobble.clone();
62 if let Some(new_track_name) = &self.edit.track_name {
63 modified_edit.track_name = new_track_name.clone();
64 }
65 if let Some(new_album_name) = &self.edit.album_name {
66 modified_edit.album_name = new_album_name.clone();
67 }
68 modified_edit.artist_name = self.edit.artist_name.clone();
69 if let Some(new_album_artist_name) = &self.edit.album_artist_name {
70 modified_edit.album_artist_name = new_album_artist_name.clone();
71 }
72 modified_edit.edit_all = self.edit.edit_all;
73 modified_edits.push(modified_edit);
74 }
75
76 let filtered_edits =
77 filter_by_original_album_artist(modified_edits, &self.edit);
78
79 if !filtered_edits.is_empty() {
80 self.current_results = filtered_edits;
82 self.current_index = 1; self.scrobbles_loaded = true;
84 return Ok(Some(self.current_results[0].clone()));
85 }
86 }
87 Err(e) => {
88 log::debug!(
89 "Failed to get scrobble data for track '{}': {}",
90 self.track_name,
91 e
92 );
93 self.scrobbles_loaded = true;
94 return Err(e);
95 }
96 }
97 self.scrobbles_loaded = true;
98 }
99
100 Ok(None)
102 }
103}