csaf_walker/source/
mod.rs

1//! Sources
2
3mod descriptor;
4mod dispatch;
5mod file;
6mod http;
7
8pub use descriptor::*;
9pub use dispatch::*;
10pub use file::*;
11pub use http::*;
12
13use crate::{
14    discover::{DiscoverConfig, DiscoveredAdvisory, DistributionContext},
15    model::metadata::ProviderMetadata,
16    retrieve::RetrievedAdvisory,
17};
18use std::{fmt::Debug, future::Future, str::FromStr};
19use walker_common::fetcher::FetcherOptions;
20
21/// A source of CSAF documents
22pub trait Source: walker_common::source::Source + Clone + Debug {
23    fn load_metadata(&self) -> impl Future<Output = Result<ProviderMetadata, Self::Error>>;
24
25    fn load_index(
26        &self,
27        context: DistributionContext,
28    ) -> impl Future<Output = Result<Vec<DiscoveredAdvisory>, Self::Error>>;
29
30    fn load_advisory(
31        &self,
32        advisory: DiscoveredAdvisory,
33    ) -> impl Future<Output = Result<RetrievedAdvisory, Self::Error>>;
34}
35
36/// A common way to create a new CSAF source.
37pub async fn new_source(
38    discover: impl Into<DiscoverConfig>,
39    fetcher: impl Into<FetcherOptions>,
40) -> anyhow::Result<DispatchSource> {
41    let discover = discover.into();
42
43    let descriptor = SourceDescriptor::from_str(&discover.source)?;
44    descriptor.into_source(discover, fetcher.into()).await
45}