Skip to main content

do_over/
policy.rs

1//! Core policy trait for resilience patterns.
2//!
3//! All resilience policies in do_over implement the [`Policy`] trait, which
4//! provides a uniform interface for executing operations with resilience.
5
6use std::future::Future;
7
8/// The core trait implemented by all resilience policies.
9///
10/// `Policy<E>` provides a uniform interface for wrapping async operations
11/// with resilience patterns like retry, circuit breaker, timeout, etc.
12///
13/// # Type Parameter
14///
15/// * `E` - The error type that the policy can produce
16///
17/// # Examples
18///
19/// Using a policy to execute an operation:
20///
21/// ```rust
22/// use do_over::{policy::Policy, retry::RetryPolicy};
23/// use std::time::Duration;
24///
25/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
26/// let policy = RetryPolicy::fixed(3, Duration::from_millis(100));
27///
28/// let result = policy.execute(|| async {
29///     // Your async operation here
30///     Ok::<_, std::io::Error>("success")
31/// }).await?;
32/// # Ok(())
33/// # }
34/// ```
35///
36/// # Implementing Policy
37///
38/// To create a custom policy, implement this trait:
39///
40/// ```rust
41/// use do_over::policy::Policy;
42/// use std::future::Future;
43///
44/// struct LoggingPolicy;
45///
46/// #[async_trait::async_trait]
47/// impl<E: Send + Sync> Policy<E> for LoggingPolicy {
48///     async fn execute<F, Fut, T>(&self, f: F) -> Result<T, E>
49///     where
50///         F: Fn() -> Fut + Send + Sync,
51///         Fut: Future<Output = Result<T, E>> + Send,
52///         T: Send,
53///     {
54///         println!("Executing operation...");
55///         let result = f().await;
56///         println!("Operation completed");
57///         result
58///     }
59/// }
60/// ```
61#[async_trait::async_trait]
62pub trait Policy<E>: Send + Sync {
63    /// Execute an async operation with this policy's resilience behavior.
64    ///
65    /// # Arguments
66    ///
67    /// * `f` - A closure that returns a Future producing `Result<T, E>`
68    ///
69    /// # Returns
70    ///
71    /// The result of the operation, potentially modified by the policy
72    /// (e.g., retried, timed out, etc.)
73    async fn execute<F, Fut, T>(&self, f: F) -> Result<T, E>
74    where
75        F: Fn() -> Fut + Send + Sync,
76        Fut: Future<Output = Result<T, E>> + Send,
77        T: Send;
78}