micromegas_telemetry_sink/
request_decorator.rs

1use std::fmt::Display;
2
3use async_trait::async_trait;
4
5/// An error that can occur when decorating a request.
6///
7/// Depending on the type of error, the request may be retried at a later time.
8#[derive(Debug)]
9pub enum RequestDecoratorError {
10    /// A permanent error occurred while decorating the request.
11    ///
12    /// No further attempts to decorate the request should be made.
13    Permanent(String),
14
15    /// A transient error occurred while decorating the request.
16    ///
17    /// The request may be retried at a later time.
18    Transient(String),
19}
20
21impl Display for RequestDecoratorError {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        match self {
24            RequestDecoratorError::Permanent(msg) => {
25                write!(f, "failed to decorate request: permanent error: {msg}")
26            }
27            RequestDecoratorError::Transient(msg) => {
28                write!(f, "failed to decorate request: transient error: {msg}")
29            }
30        }
31    }
32}
33
34impl std::error::Error for RequestDecoratorError {}
35
36impl From<RequestDecoratorError> for tokio_retry2::RetryError<anyhow::Error> {
37    fn from(value: RequestDecoratorError) -> Self {
38        match value {
39            RequestDecoratorError::Permanent(msg) => tokio_retry2::RetryError::permanent(
40                anyhow::anyhow!("failed to decorate request: {msg}"),
41            ),
42            RequestDecoratorError::Transient(msg) => tokio_retry2::RetryError::transient(
43                anyhow::anyhow!("failed to decorate request: {msg}"),
44            ),
45        }
46    }
47}
48
49/// A result type for request decorators.
50pub type Result<T> = std::result::Result<T, RequestDecoratorError>;
51
52#[async_trait] // otherwise we get: cannot be made into an object
53pub trait RequestDecorator: Send {
54    /// Decorates the given `reqwest::Request`.
55    ///
56    /// This function can modify the request (e.g., add headers, sign the request)
57    /// before it is sent.
58    ///
59    /// # Arguments
60    ///
61    /// * `request` - A mutable reference to the `reqwest::Request` to decorate.
62    async fn decorate(&self, request: &mut reqwest::Request) -> Result<()>;
63}
64
65pub struct TrivialRequestDecorator {}
66
67#[async_trait]
68impl RequestDecorator for TrivialRequestDecorator {
69    async fn decorate(&self, _request: &mut reqwest::Request) -> Result<()> {
70        Ok(())
71    }
72}