csaf_walker/source/
dispatch.rs1use super::{HttpSourceError, Source};
2use crate::discover::{DiscoveredAdvisory, DistributionContext};
3use crate::model::metadata::ProviderMetadata;
4use crate::retrieve::RetrievedAdvisory;
5use crate::source::{FileSource, HttpSource};
6use walker_common::{
7 utils::openpgp::PublicKey,
8 validate::source::{Key, KeySource, KeySourceError, MapSourceError},
9};
10
11#[derive(Clone, Debug)]
19pub enum DispatchSource {
20 File(FileSource),
21 Http(HttpSource),
22}
23
24impl From<FileSource> for DispatchSource {
25 fn from(value: FileSource) -> Self {
26 Self::File(value)
27 }
28}
29
30impl From<HttpSource> for DispatchSource {
31 fn from(value: HttpSource) -> Self {
32 Self::Http(value)
33 }
34}
35
36#[derive(Debug, thiserror::Error)]
37pub enum DispatchSourceError {
38 #[error(transparent)]
39 File(anyhow::Error),
40 #[error(transparent)]
41 Http(HttpSourceError),
42}
43
44impl walker_common::source::Source for DispatchSource {
45 type Error = DispatchSourceError;
46 type Retrieved = RetrievedAdvisory;
47}
48
49impl Source for DispatchSource {
50 async fn load_metadata(&self) -> Result<ProviderMetadata, Self::Error> {
51 match self {
52 Self::File(source) => source
53 .load_metadata()
54 .await
55 .map_err(DispatchSourceError::File),
56 Self::Http(source) => source
57 .load_metadata()
58 .await
59 .map_err(DispatchSourceError::Http),
60 }
61 }
62
63 async fn load_index(
64 &self,
65 context: DistributionContext,
66 ) -> Result<Vec<DiscoveredAdvisory>, Self::Error> {
67 match self {
68 Self::File(source) => source
69 .load_index(context)
70 .await
71 .map_err(DispatchSourceError::File),
72 Self::Http(source) => source
73 .load_index(context)
74 .await
75 .map_err(DispatchSourceError::Http),
76 }
77 }
78
79 async fn load_advisory(
80 &self,
81 advisory: DiscoveredAdvisory,
82 ) -> Result<RetrievedAdvisory, Self::Error> {
83 match self {
84 Self::File(source) => source
85 .load_advisory(advisory)
86 .await
87 .map_err(DispatchSourceError::File),
88 Self::Http(source) => source
89 .load_advisory(advisory)
90 .await
91 .map_err(DispatchSourceError::Http),
92 }
93 }
94}
95
96impl KeySource for DispatchSource {
97 type Error = anyhow::Error;
98
99 async fn load_public_key(
100 &self,
101 key: Key<'_>,
102 ) -> Result<PublicKey, KeySourceError<Self::Error>> {
103 match self {
104 Self::File(source) => source.load_public_key(key).await,
105 Self::Http(source) => source
106 .load_public_key(key)
107 .await
108 .map_source(|err| err.into()),
109 }
110 }
111}