lastfm_edit/discovery/
exact_match.rs1use super::common::filter_by_original_album_artist;
2use crate::{
3 AsyncDiscoveryIterator, ExactScrobbleEdit, LastFmEditClientImpl, LastFmError, Result,
4 ScrobbleEdit,
5};
6use async_trait::async_trait;
7
8pub struct ExactMatchDiscovery {
13 client: LastFmEditClientImpl,
14 edit: ScrobbleEdit,
15 track_name: String,
16 album_name: String,
17 result: Option<ExactScrobbleEdit>,
18 completed: bool,
19}
20
21impl ExactMatchDiscovery {
22 pub fn new(
23 client: LastFmEditClientImpl,
24 edit: ScrobbleEdit,
25 track_name: String,
26 album_name: String,
27 ) -> Self {
28 Self {
29 client,
30 edit,
31 track_name,
32 album_name,
33 result: None,
34 completed: false,
35 }
36 }
37}
38
39#[async_trait(?Send)]
40impl AsyncDiscoveryIterator<ExactScrobbleEdit> for ExactMatchDiscovery {
41 async fn next(&mut self) -> Result<Option<ExactScrobbleEdit>> {
42 if self.completed {
43 return Ok(None);
44 }
45
46 if self.result.is_none() {
47 log::debug!(
49 "Looking up missing metadata for track '{}' on album '{}' by '{}'",
50 self.track_name,
51 self.album_name,
52 self.edit.artist_name_original
53 );
54
55 match self
56 .client
57 .load_edit_form_values_internal(&self.track_name, &self.edit.artist_name_original)
58 .await
59 {
60 Ok(all_variations) => {
61 let filtered_variations =
63 filter_by_original_album_artist(all_variations, &self.edit);
64
65 if let Some(exact_edit) = filtered_variations
66 .iter()
67 .find(|variation| variation.album_name_original == self.album_name)
68 {
69 let mut modified_edit = exact_edit.clone();
71 if let Some(new_track_name) = &self.edit.track_name {
72 modified_edit.track_name = new_track_name.clone();
73 }
74 if let Some(new_album_name) = &self.edit.album_name {
75 modified_edit.album_name = new_album_name.clone();
76 }
77 modified_edit.artist_name = self.edit.artist_name.clone();
78 if let Some(new_album_artist_name) = &self.edit.album_artist_name {
79 modified_edit.album_artist_name = new_album_artist_name.clone();
80 }
81 modified_edit.edit_all = self.edit.edit_all;
82
83 self.result = Some(modified_edit);
84 } else {
85 let album_artist_filter = if self.edit.album_artist_name_original.is_some()
86 {
87 format!(
88 " with album artist '{}'",
89 self.edit.album_artist_name_original.as_ref().unwrap()
90 )
91 } else {
92 String::new()
93 };
94 self.completed = true;
95 return Err(LastFmError::Parse(format!(
96 "Track '{}' not found on album '{}' by '{}'{} in recent scrobbles",
97 self.track_name,
98 self.album_name,
99 self.edit.artist_name_original,
100 album_artist_filter
101 )));
102 }
103 }
104 Err(e) => {
105 self.completed = true;
106 return Err(e);
107 }
108 }
109 }
110
111 self.completed = true;
112 Ok(self.result.take())
113 }
114}