use crate::discover::DiscoveredSbom;
use crate::model::metadata::SourceMetadata;
use crate::retrieve::RetrievedSbom;
use crate::source::{FileSource, HttpSource, Source};
use async_trait::async_trait;
use walker_common::{
utils::openpgp::PublicKey,
validate::source::{Key, KeySource, KeySourceError, MapSourceError},
};
#[derive(Clone)]
pub enum DispatchSource {
Http(HttpSource),
File(FileSource),
}
impl From<HttpSource> for DispatchSource {
fn from(value: HttpSource) -> Self {
Self::Http(value)
}
}
impl From<FileSource> for DispatchSource {
fn from(value: FileSource) -> Self {
Self::File(value)
}
}
#[async_trait(?Send)]
impl Source for DispatchSource {
type Error = anyhow::Error;
async fn load_metadata(&self) -> Result<SourceMetadata, Self::Error> {
match self {
Self::Http(source) => Ok(source.load_metadata().await?),
Self::File(source) => Ok(source.load_metadata().await?),
}
}
async fn load_index(&self) -> Result<Vec<DiscoveredSbom>, Self::Error> {
match self {
Self::Http(source) => Ok(source.load_index().await?),
Self::File(source) => Ok(source.load_index().await?),
}
}
async fn load_sbom(&self, sbom: DiscoveredSbom) -> Result<RetrievedSbom, Self::Error> {
match self {
Self::Http(source) => Ok(source.load_sbom(sbom).await?),
Self::File(source) => Ok(source.load_sbom(sbom).await?),
}
}
}
#[async_trait(?Send)]
impl KeySource for DispatchSource {
type Error = anyhow::Error;
async fn load_public_key<'a>(
&self,
key: Key<'a>,
) -> Result<PublicKey, KeySourceError<Self::Error>> {
match self {
Self::Http(source) => source
.load_public_key(key)
.await
.map_source(|err| err.into()),
Self::File(source) => source.load_public_key(key).await,
}
}
}