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