|
1 | | -use std::sync::Arc; |
2 | | - |
3 | | -use crate::print_colorized; |
4 | | -use crate::provider::Provider; |
| 1 | +use std::{collections::HashMap, sync::Arc}; |
5 | 2 |
|
6 | 3 | #[cfg(feature = "cache")] |
7 | 4 | use crate::cache; |
| 5 | +use crate::{print_colorized, provider::Provider}; |
8 | 6 |
|
9 | 7 | #[cfg(feature = "cache")] |
10 | 8 | pub async fn process_with_cache<I: IntoIterator<Item = String>>( |
11 | 9 | providers: Vec<Arc<Box<dyn Provider>>>, |
12 | 10 | cache: &cache::Cache, |
13 | 11 | avatar_ids: I, |
14 | 12 | ) -> anyhow::Result<()> { |
15 | | - let checked_ids = cache.check_all_ids(avatar_ids).await?; |
| 13 | + let checked_ids = cache |
| 14 | + .check_all_ids(avatar_ids) |
| 15 | + .await? |
| 16 | + .into_iter() |
| 17 | + .collect::<Vec<_>>(); |
16 | 18 |
|
17 | 19 | let (tx, rx) = flume::unbounded(); |
| 20 | + let checked_ids = Arc::new(checked_ids); |
| 21 | + let mut base_bits = HashMap::new(); |
18 | 22 |
|
19 | | - for (id, provider_bits) in checked_ids { |
20 | | - print_colorized(&id); |
| 23 | + for (id, provider_bits) in checked_ids.iter() { |
| 24 | + print_colorized(id); |
| 25 | + base_bits.insert(id.clone(), *provider_bits); |
| 26 | + } |
21 | 27 |
|
22 | | - for p in providers |
23 | | - .iter() |
24 | | - .filter(|provider| provider_bits & provider.kind() as u32 == 0) |
25 | | - { |
26 | | - let p = p.clone(); |
27 | | - let id_clone = id.clone(); |
28 | | - let tx_clone = tx.clone(); |
29 | | - tokio::spawn(async move { |
30 | | - let kind = p.kind(); |
31 | | - match p.send_avatar_id(&id_clone).await { |
| 28 | + for provider in &providers { |
| 29 | + let provider = provider.clone(); |
| 30 | + let tx_clone = tx.clone(); |
| 31 | + let checked_ids = checked_ids.clone(); |
| 32 | + tokio::spawn(async move { |
| 33 | + let kind = provider.kind(); |
| 34 | + let kind_bit = kind as u32; |
| 35 | + for (id, provider_bits) in checked_ids.iter() { |
| 36 | + if provider_bits & kind_bit != 0 { |
| 37 | + continue; |
| 38 | + } |
| 39 | + match provider.send_avatar_id(id).await { |
32 | 40 | Ok(success) => { |
33 | 41 | if success { |
34 | 42 | info!("^ Successfully Submitted to {kind}"); |
35 | | - let _ = tx_clone |
36 | | - .send_async((id_clone, provider_bits | kind as u32)) |
37 | | - .await; |
| 43 | + let _ = tx_clone.send_async((id.clone(), kind_bit)).await; |
38 | 44 | } |
39 | 45 | } |
40 | 46 | Err(err) => { |
41 | 47 | error!("^ Failed to submit to {kind}: {err}"); |
42 | 48 | } |
43 | 49 | } |
44 | | - }); |
45 | | - } |
| 50 | + } |
| 51 | + }); |
46 | 52 | } |
47 | 53 |
|
48 | 54 | drop(tx); |
49 | 55 |
|
50 | | - let mut buffer = Vec::new(); |
| 56 | + let mut updated_bits = HashMap::new(); |
51 | 57 |
|
52 | | - while let Ok(msg) = rx.recv_async().await { |
53 | | - buffer.push(msg); |
| 58 | + while let Ok((id, kind_bit)) = rx.recv_async().await { |
| 59 | + let entry = updated_bits.entry(id).or_insert(0); |
| 60 | + *entry |= kind_bit; |
| 61 | + } |
| 62 | + |
| 63 | + let mut buffer = Vec::new(); |
| 64 | + for (id, bits) in base_bits { |
| 65 | + if let Some(add_bits) = updated_bits.get(&id) { |
| 66 | + buffer.push((id, bits | add_bits)); |
| 67 | + } |
54 | 68 | } |
55 | 69 |
|
56 | 70 | cache.store_avatar_ids_with_providers(buffer).await |
@@ -90,19 +104,20 @@ pub async fn process_without_cache<I: IntoIterator<Item = String>>( |
90 | 104 |
|
91 | 105 | #[cfg(test)] |
92 | 106 | mod tests { |
93 | | - use crate::provider::ProviderKind; |
| 107 | + use std::sync::Arc; |
94 | 108 |
|
95 | | - use super::*; |
96 | 109 | use anyhow::Result; |
97 | 110 | use async_trait::async_trait; |
98 | | - use std::sync::Arc; |
99 | 111 | use strum::IntoEnumIterator; |
100 | 112 | use tokio::sync::Mutex; |
101 | 113 |
|
| 114 | + use super::*; |
| 115 | + use crate::provider::ProviderKind; |
| 116 | + |
102 | 117 | #[derive(Clone)] |
103 | 118 | struct MockProvider { |
104 | | - kind: ProviderKind, |
105 | | - sent: Arc<Mutex<Vec<String>>>, |
| 119 | + kind: ProviderKind, |
| 120 | + sent: Arc<Mutex<Vec<String>>>, |
106 | 121 | succeed: bool, |
107 | 122 | } |
108 | 123 |
|
|
0 commit comments