1use memberlist_core::{CheapClone, transport::Id};
2
3use crate::types::Member;
4
5use super::{
6 DefaultMergeDelegate, Delegate, MergeDelegate, NoopReconnectDelegate, ReconnectDelegate,
7};
8
9use std::sync::Arc;
10
11pub struct CompositeDelegate<I, A, M = DefaultMergeDelegate<I, A>, R = NoopReconnectDelegate<I, A>>
15{
16 merge: M,
17 reconnect: R,
18 _m: std::marker::PhantomData<(I, A)>,
19}
20
21impl<I, A> Default for CompositeDelegate<I, A> {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl<I, A> CompositeDelegate<I, A> {
28 pub fn new() -> Self {
30 Self {
31 merge: Default::default(),
32 reconnect: Default::default(),
33 _m: std::marker::PhantomData,
34 }
35 }
36}
37
38impl<I, A, M, R> CompositeDelegate<I, A, M, R>
39where
40 M: MergeDelegate<Id = I, Address = A>,
41{
42 pub fn with_merge_delegate<NM>(self, merge: NM) -> CompositeDelegate<I, A, NM, R> {
44 CompositeDelegate {
45 merge,
46 reconnect: self.reconnect,
47 _m: std::marker::PhantomData,
48 }
49 }
50}
51
52impl<I, A, M, R> CompositeDelegate<I, A, M, R> {
53 pub fn with_reconnect_delegate<NR>(self, reconnect: NR) -> CompositeDelegate<I, A, M, NR> {
55 CompositeDelegate {
56 reconnect,
57 merge: self.merge,
58 _m: std::marker::PhantomData,
59 }
60 }
61}
62
63impl<I, A, M, R> MergeDelegate for CompositeDelegate<I, A, M, R>
64where
65 I: Id + Send + Sync + 'static,
66 A: CheapClone + Send + Sync + 'static,
67 M: MergeDelegate<Id = I, Address = A>,
68 R: Send + Sync + 'static,
69{
70 type Error = M::Error;
71
72 type Id = M::Id;
73
74 type Address = M::Address;
75
76 async fn notify_merge(
77 &self,
78 members: Arc<[Member<Self::Id, Self::Address>]>,
79 ) -> Result<(), Self::Error> {
80 self.merge.notify_merge(members).await
81 }
82}
83
84impl<I, A, M, R> ReconnectDelegate for CompositeDelegate<I, A, M, R>
85where
86 I: Id + Send + Sync + 'static,
87 A: CheapClone + Send + Sync + 'static,
88 M: Send + Sync + 'static,
89 R: ReconnectDelegate<Id = I, Address = A>,
90{
91 type Id = R::Id;
92
93 type Address = R::Address;
94
95 fn reconnect_timeout(
96 &self,
97 member: &Member<Self::Id, Self::Address>,
98 timeout: std::time::Duration,
99 ) -> std::time::Duration {
100 self.reconnect.reconnect_timeout(member, timeout)
101 }
102}
103
104impl<I, A, M, R> Delegate for CompositeDelegate<I, A, M, R>
105where
106 I: Id + Send + Sync + 'static,
107 A: CheapClone + Send + Sync + 'static,
108 M: MergeDelegate<Id = I, Address = A>,
109 R: ReconnectDelegate<Id = I, Address = A>,
110{
111 type Id = I;
112
113 type Address = A;
114}