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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//! Provides a trait for acknowledging messages in an asynchronous context.
//!
//! Acknowledgement is a common pattern in distributed systems, especially in
//! message-driven architectures. This module introduces a trait, `Acker`, which
//! abstracts the act of acknowledging a message. This abstraction allows for a
//! consistent interface across different components or systems that require
//! message acknowledgement.
//!
//! The trait is designed with async/await in mind, ensuring that
//! acknowledgements can be handled in an asynchronous manner without blocking
//! the main thread.
//!
//! # Features:
//! - **Asynchronous**: Uses async/await for non-blocking operations.
//! - **Generic Implementation for Boxed Types**: Allows for easy integration
//! with boxed types, ensuring flexibility in usage.
//!
//! # Examples
//!
//! Implementing the `Acker` trait for a custom type:
//!
//! ```
//! use paladin::acker::Acker;
//! use anyhow::Result;
//! use async_trait::async_trait;
//!
//! struct MyAcker;
//!
//! #[async_trait]
//! impl Acker for MyAcker {
//! async fn ack(&self) -> Result<()> {
//! // Custom acknowledgement logic here...
//! Ok(())
//! }
//!
//! async fn nack(&self) -> Result<()> {
//! // Custom negative acknowledgement logic here...
//! Ok(())
//! }
//! }
//! ```
//!
//! Using the `Acker` trait with boxed types:
//!
//! ```
//! # use paladin::acker::Acker;
//! # use anyhow::Result;
//! # use async_trait::async_trait;
//! # struct MyAcker;
//! #
//! # #[async_trait]
//! # impl Acker for MyAcker {
//! # async fn ack(&self) -> Result<()> {
//! # // Custom acknowledgement logic here...
//! # Ok(())
//! # }
//! #
//! # async fn nack(&self) -> Result<()> {
//! # // Custom negative acknowledgement logic here...
//! # Ok(())
//! # }
//! # }
//! # #[tokio::main]
//! # async fn main() -> Result<()> {
//! let my_acker: Box<MyAcker> = Box::new(MyAcker);
//! my_acker.ack().await?;
//! # Ok(())
//! # }
//! ```
use Arc;
use Result;
use async_trait;
use TryFutureExt;
/// Represents a generic behavior for acknowledging messages.
///
/// This trait provides a unified interface for components that require message
/// acknowledgement. Implementers of this trait should provide the actual logic
/// for acknowledging a message in the `ack` and `nack` methods.
/// Provides an implementation of the `Acker` trait for boxed types.
///
/// This allows for flexibility in using the `Acker` trait with dynamically
/// dispatched types.
/// Provides an implementation of the `Acker` trait for `Arc` types.
/// An `Acker` implementation that composes two `Acker` instances.
///
/// The `ack` and `nack` methods on the second `Acker` instance will only be
/// called if the first `Acker` instance succeeds.
/// Acker implementation that does nothing.
///
/// Useful for testing purposes where channels are emulated in-memory.
;