walker_extras/visitors/send/
csaf.rs1use super::*;
2use crate::csaf::{
3 retrieve::{RetrievalContext, RetrievedAdvisory, RetrievedVisitor},
4 validation::{ValidatedAdvisory, ValidatedVisitor, ValidationContext, ValidationError},
5};
6use csaf_walker::{discover::DiscoveredAdvisory, source::Source};
7use walker_common::retrieve::RetrievalError;
8
9#[derive(Debug, thiserror::Error)]
10pub enum SendRetrievedAdvisoryError<S: Source> {
11 #[error(transparent)]
12 Store(#[from] SendError),
13 #[error(transparent)]
14 Retrieval(#[from] RetrievalError<DiscoveredAdvisory, S>),
15}
16
17impl<S: Source> RetrievedVisitor<S> for SendVisitor {
18 type Error = SendRetrievedAdvisoryError<S>;
19 type Context = ();
20
21 async fn visit_context(&self, _: &RetrievalContext<'_>) -> Result<Self::Context, Self::Error> {
22 Ok(())
23 }
24
25 async fn visit_advisory(
26 &self,
27 _context: &Self::Context,
28 result: Result<RetrievedAdvisory, RetrievalError<DiscoveredAdvisory, S>>,
29 ) -> Result<(), Self::Error> {
30 self.send_retrieved_advisory(result?).await?;
31 Ok(())
32 }
33}
34
35#[derive(Debug, thiserror::Error)]
36pub enum SendValidatedAdvisoryError<S: Source> {
37 #[error(transparent)]
38 Store(#[from] SendError),
39 #[error(transparent)]
40 Validation(#[from] ValidationError<S>),
41}
42
43impl<S: Source> ValidatedVisitor<S> for SendVisitor {
44 type Error = SendValidatedAdvisoryError<S>;
45 type Context = ();
46
47 async fn visit_context(&self, _: &ValidationContext<'_>) -> Result<Self::Context, Self::Error> {
48 Ok(())
49 }
50
51 async fn visit_advisory(
52 &self,
53 _context: &Self::Context,
54 result: Result<ValidatedAdvisory, ValidationError<S>>,
55 ) -> Result<(), Self::Error> {
56 self.send_retrieved_advisory(result?.retrieved).await?;
57 Ok(())
58 }
59}
60
61impl SendVisitor {
62 async fn send_retrieved_advisory(&self, advisory: RetrievedAdvisory) -> Result<(), SendError> {
63 log::debug!(
64 "Sending: {} (modified: {:?})",
65 advisory.url,
66 advisory.metadata.last_modification
67 );
68
69 let RetrievedAdvisory {
70 data,
71 discovered: DiscoveredAdvisory { url, .. },
72 ..
73 } = advisory;
74
75 self.send_advisory(url.as_str(), data).await
76 }
77
78 pub async fn send_advisory(&self, name: &str, data: Bytes) -> Result<(), SendError> {
79 self.send(name, data, |request| {
80 request.header(header::CONTENT_TYPE, "application/json")
81 })
82 .await
83 }
84}