Skip to main content

anni_provider/providers/
multiple.rs

1use crate::{AnniProvider, AudioInfo, AudioResourceReader, ProviderError, Range, ResourceReader};
2use async_trait::async_trait;
3use std::borrow::Cow;
4use std::collections::HashSet;
5use std::num::NonZeroU8;
6
7/// [MultipleProviders] combines multiple anni providers as a whole.
8pub struct MultipleProviders(Vec<Box<dyn AnniProvider + Send + Sync>>);
9
10impl MultipleProviders {
11    pub fn new(providers: Vec<Box<dyn AnniProvider + Send + Sync>>) -> Self {
12        Self(providers)
13    }
14}
15
16#[async_trait]
17impl AnniProvider for MultipleProviders {
18    async fn albums(&self) -> crate::Result<HashSet<Cow<str>>> {
19        let mut albums: HashSet<Cow<str>> = HashSet::new();
20        for provider in self.0.iter() {
21            albums.extend(provider.albums().await?);
22        }
23        Ok(albums)
24    }
25
26    async fn has_album(&self, album_id: &str) -> bool {
27        for provider in self.0.iter() {
28            if provider.has_album(album_id).await {
29                return true;
30            }
31        }
32
33        return false;
34    }
35
36    async fn get_audio_info(
37        &self,
38        album_id: &str,
39        disc_id: NonZeroU8,
40        track_id: NonZeroU8,
41    ) -> crate::Result<AudioInfo> {
42        for provider in self.0.iter() {
43            if provider.has_album(album_id).await {
44                return provider.get_audio_info(album_id, disc_id, track_id).await;
45            }
46        }
47
48        Err(ProviderError::FileNotFound)
49    }
50
51    async fn get_audio(
52        &self,
53        album_id: &str,
54        disc_id: NonZeroU8,
55        track_id: NonZeroU8,
56        range: Range,
57    ) -> crate::Result<AudioResourceReader> {
58        for provider in self.0.iter() {
59            if provider.has_album(album_id).await {
60                return provider.get_audio(album_id, disc_id, track_id, range).await;
61            }
62        }
63
64        Err(ProviderError::FileNotFound)
65    }
66
67    async fn get_cover(
68        &self,
69        album_id: &str,
70        disc_id: Option<NonZeroU8>,
71    ) -> crate::Result<ResourceReader> {
72        for provider in self.0.iter() {
73            if provider.has_album(album_id).await {
74                return provider.get_cover(album_id, disc_id).await;
75            }
76        }
77
78        Err(ProviderError::FileNotFound)
79    }
80
81    async fn reload(&mut self) -> crate::Result<()> {
82        let mut error = Ok(());
83        for provider in self.0.iter_mut() {
84            if let (Ok(()), Err(e)) = (&error, provider.reload().await) {
85                error = Err(e);
86            }
87        }
88
89        error
90    }
91}