1use crate::{model::metadata, model::metadata::SourceMetadata};
4use std::{fmt::Debug, future::Future, ops::Deref, time::SystemTime};
5use url::Url;
6use walker_common::utils::url::Urlify;
7
8pub struct DiscoverConfig {
10 pub source: String,
12
13 pub since: Option<SystemTime>,
16
17 pub keys: Vec<metadata::Key>,
19}
20
21impl DiscoverConfig {
22 pub fn with_since(mut self, since: impl Into<Option<SystemTime>>) -> Self {
23 self.since = since.into();
24 self
25 }
26}
27
28#[derive(Clone, Debug, PartialEq, Eq)]
29pub struct DiscoveredSbom {
30 pub url: Url,
32 pub modified: SystemTime,
34}
35
36impl Urlify for DiscoveredSbom {
37 fn url(&self) -> &Url {
38 &self.url
39 }
40}
41
42#[derive(Debug)]
43pub struct DiscoveredContext<'c> {
44 pub metadata: &'c SourceMetadata,
45}
46
47impl Deref for DiscoveredContext<'_> {
48 type Target = SourceMetadata;
49
50 fn deref(&self) -> &Self::Target {
51 self.metadata
52 }
53}
54
55pub trait DiscoveredVisitor {
57 type Error: std::fmt::Display + Debug;
58 type Context;
59
60 fn visit_context(
61 &self,
62 context: &DiscoveredContext,
63 ) -> impl Future<Output = Result<Self::Context, Self::Error>>;
64
65 fn visit_sbom(
66 &self,
67 context: &Self::Context,
68 sbom: DiscoveredSbom,
69 ) -> impl Future<Output = Result<(), Self::Error>>;
70}
71
72impl<F, E, Fut> DiscoveredVisitor for F
73where
74 F: Fn(DiscoveredSbom) -> Fut,
75 Fut: Future<Output = Result<(), E>>,
76 E: std::fmt::Display + Debug,
77{
78 type Error = E;
79 type Context = ();
80
81 async fn visit_context(
82 &self,
83 _context: &DiscoveredContext<'_>,
84 ) -> Result<Self::Context, Self::Error> {
85 Ok(())
86 }
87
88 async fn visit_sbom(
89 &self,
90 _context: &Self::Context,
91 sbom: DiscoveredSbom,
92 ) -> Result<(), Self::Error> {
93 self(sbom).await
94 }
95}