use crate::ManagerSorts;
use alux_ext::ext;
use ambassador::delegatable_trait;
use std::path::PathBuf;
pub trait DownloadsAlg: ManagerSorts {
fn empty_downloads(&self) -> Self::Downloads;
}
#[delegatable_trait]
pub trait SourceRequestAlg: ManagerSorts {
fn source(&self, input: impl Into<String>, output: Self::Output, options: Self::Options) -> Self::Source;
}
#[delegatable_trait]
pub trait MediaOptionsAlg: ManagerSorts {
fn progressive(&self) -> Self::Options;
fn audio(&self) -> Self::Options;
fn video(&self) -> Self::Options;
}
#[delegatable_trait]
pub trait SourceRecognitionAlg {
fn recognizes_source(&self, line: &str) -> bool;
}
#[delegatable_trait]
pub trait SubmissionAlg: ManagerSorts {
fn submitted(&self, line: &str) -> Self::Source;
}
#[delegatable_trait]
pub trait OutputChoiceAlg: ManagerSorts {
fn suggested_output(&self) -> Self::Output;
fn exact_output(&self, path: impl Into<PathBuf>) -> Self::Output;
}
pub trait DownloadCollectionAlg: ManagerSorts {
#[must_use]
fn add_sources(self, sources: impl IntoIterator<Item = Self::Source>) -> Self;
}
#[ext(name = DownloadsExt)]
pub impl<This> This
where
This: DownloadsAlg + SourceRequestAlg,
This::Downloads: DownloadCollectionAlg<Source = This::Source>,
{
fn downloads(&self, sources: impl IntoIterator<Item = This::Source>) -> This::Downloads {
self.empty_downloads().add_sources(sources)
}
}
#[ext(name = ProgressiveDownloadsExt)]
pub impl<This> This
where
This: DownloadsAlg + SourceRequestAlg + MediaOptionsAlg + OutputChoiceAlg,
This::Downloads: DownloadCollectionAlg<Source = This::Source>,
{
fn progressive_downloads(&self, sources: impl IntoIterator<Item = impl Into<String>>) -> This::Downloads {
self.downloads(
sources.into_iter().map(|source| self.source(source, self.suggested_output(), self.progressive())),
)
}
}