1use anni_provider::{AnniProvider, ProviderError};
2use std::ops::{Deref, DerefMut};
3use tokio::sync::RwLock;
4
5pub struct AnnilProvider<T: AnniProvider + Send + Sync>(RwLock<T>);
6
7impl<T: AnniProvider + Send + Sync> AnnilProvider<T> {
8 pub fn new(provider: T) -> Self {
9 Self(RwLock::new(provider))
10 }
11
12 pub async fn compute_etag(&self) -> Result<String, ProviderError> {
13 use base64::engine::general_purpose::STANDARD;
14 use base64::Engine;
15
16 let provider = self.0.read().await;
17
18 let mut etag = 0;
19 for album in provider.albums().await? {
20 if let Ok(uuid) = uuid::Uuid::parse_str(album.as_ref()) {
21 etag ^= uuid.as_u128();
22 } else {
23 log::error!("Failed to parse uuid: {album}");
24 }
25 }
26
27 Ok(format!(r#""{}""#, STANDARD.encode(etag.to_be_bytes())))
28 }
29}
30
31impl<T: AnniProvider + Send + Sync> Deref for AnnilProvider<T> {
32 type Target = RwLock<T>;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl<T: AnniProvider + Send + Sync> DerefMut for AnnilProvider<T> {
40 fn deref_mut(&mut self) -> &mut Self::Target {
41 &mut self.0
42 }
43}