@@ -8,6 +8,7 @@ use std::env;
8
8
use std:: fmt:: Debug ;
9
9
use std:: ops:: Deref ;
10
10
use std:: path:: Path ;
11
+ use std:: slice:: Iter ;
11
12
use std:: sync:: Arc ;
12
13
use tracing:: debug;
13
14
use uv_auth:: AuthMiddleware ;
@@ -20,69 +21,76 @@ use crate::linehaul::LineHaul;
20
21
use crate :: middleware:: OfflineMiddleware ;
21
22
use crate :: Connectivity ;
22
23
23
- #[ derive( Clone , Default ) ]
24
- pub struct CustomMiddleware {
25
- pub middleware : Vec < Arc < dyn Middleware > > ,
24
+ /// Newtype to implement [`Debug`] on [`Middleware`].
25
+ #[ derive( Clone ) ]
26
+ pub struct MiddlewareStack ( Vec < Arc < dyn Middleware > > ) ;
27
+
28
+ impl MiddlewareStack {
29
+ /// Use a custom middleware stack, skipping the default retry and auth layers.
30
+ // This function exists for rustlib users.
31
+ pub fn custom ( middleware_stack : Vec < Arc < dyn Middleware > > ) -> Self {
32
+ Self ( middleware_stack)
33
+ }
34
+
35
+ /// Initialize the middleware stack, using an [`ExponentialBackoff`] with the given number of
36
+ /// retries and an [`AuthMiddleware`] layer with the given keyring provider.
37
+ pub fn new ( retries : u32 , keyring : KeyringProviderType ) -> Self {
38
+ let retry_policy = ExponentialBackoff :: builder ( ) . build_with_max_retries ( retries) ;
39
+ let retry_strategy = RetryTransientMiddleware :: new_with_policy ( retry_policy) ;
40
+
41
+ let auth_middleware = AuthMiddleware :: new ( ) . with_keyring ( keyring. to_provider ( ) ) ;
42
+
43
+ Self ( vec ! [ Arc :: new( retry_strategy) , Arc :: new( auth_middleware) ] )
44
+ }
26
45
}
27
- impl Debug for CustomMiddleware {
46
+
47
+ impl Default for MiddlewareStack {
48
+ /// Initialize the default middleware stack, consisting of an [`ExponentialBackoff`] retry
49
+ /// strategy and an [`AuthMiddleware`] layer not using the keyring.
50
+ fn default ( ) -> Self {
51
+ Self :: new ( 3 , KeyringProviderType :: default ( ) )
52
+ }
53
+ }
54
+
55
+ impl Debug for MiddlewareStack {
28
56
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
29
57
f. debug_struct ( "CustomMiddleware" ) . finish ( )
30
58
}
31
59
}
32
60
61
+ impl < ' a > IntoIterator for & ' a MiddlewareStack {
62
+ type Item = & ' a Arc < dyn Middleware > ;
63
+ type IntoIter = Iter < ' a , Arc < dyn Middleware > > ;
64
+
65
+ fn into_iter ( self ) -> Self :: IntoIter {
66
+ self . 0 . iter ( )
67
+ }
68
+ }
69
+
33
70
/// A builder for an [`BaseClient`].
34
- #[ derive( Debug , Clone ) ]
71
+ #[ derive( Debug , Clone , Default ) ]
35
72
pub struct BaseClientBuilder < ' a > {
36
- keyring : KeyringProviderType ,
37
73
native_tls : bool ,
38
- retries : u32 ,
39
74
connectivity : Connectivity ,
40
75
client : Option < Client > ,
41
76
markers : Option < & ' a MarkerEnvironment > ,
42
77
platform : Option < & ' a Platform > ,
43
- custom_middleware : CustomMiddleware ,
44
- }
45
-
46
- impl Default for BaseClientBuilder < ' _ > {
47
- fn default ( ) -> Self {
48
- Self :: new ( )
49
- }
78
+ middleware_stack : MiddlewareStack ,
50
79
}
51
80
52
81
impl BaseClientBuilder < ' _ > {
53
82
pub fn new ( ) -> Self {
54
- Self {
55
- keyring : KeyringProviderType :: default ( ) ,
56
- native_tls : false ,
57
- connectivity : Connectivity :: Online ,
58
- retries : 3 ,
59
- client : None ,
60
- markers : None ,
61
- platform : None ,
62
- custom_middleware : CustomMiddleware :: default ( ) ,
63
- }
83
+ Self :: default ( )
64
84
}
65
85
}
66
86
67
87
impl < ' a > BaseClientBuilder < ' a > {
68
- #[ must_use]
69
- pub fn keyring ( mut self , keyring_type : KeyringProviderType ) -> Self {
70
- self . keyring = keyring_type;
71
- self
72
- }
73
-
74
88
#[ must_use]
75
89
pub fn connectivity ( mut self , connectivity : Connectivity ) -> Self {
76
90
self . connectivity = connectivity;
77
91
self
78
92
}
79
93
80
- #[ must_use]
81
- pub fn retries ( mut self , retries : u32 ) -> Self {
82
- self . retries = retries;
83
- self
84
- }
85
-
86
94
#[ must_use]
87
95
pub fn native_tls ( mut self , native_tls : bool ) -> Self {
88
96
self . native_tls = native_tls;
@@ -108,14 +116,8 @@ impl<'a> BaseClientBuilder<'a> {
108
116
}
109
117
110
118
#[ must_use]
111
- pub fn add_middleware < M : Middleware > ( mut self , middleware : M ) -> Self {
112
- self . custom_middleware . middleware . push ( Arc :: new ( middleware) ) ;
113
- self
114
- }
115
-
116
- #[ must_use]
117
- pub fn custom_middleware ( mut self , custom_middleware : CustomMiddleware ) -> Self {
118
- self . custom_middleware = custom_middleware;
119
+ pub fn middleware_stack ( mut self , middleware_stack : MiddlewareStack ) -> Self {
120
+ self . middleware_stack = middleware_stack;
119
121
self
120
122
}
121
123
@@ -187,26 +189,10 @@ impl<'a> BaseClientBuilder<'a> {
187
189
let client = match self . connectivity {
188
190
Connectivity :: Online => {
189
191
let mut client = reqwest_middleware:: ClientBuilder :: new ( client. clone ( ) ) ;
190
-
191
- // Use custom middleware instead if provided
192
- if !self . custom_middleware . middleware . is_empty ( ) {
193
- for middleware in & self . custom_middleware . middleware {
194
- client = client. with_arc ( middleware. clone ( ) ) ;
195
- }
196
- client. build ( )
197
- } else {
198
- // Initialize the retry strategy.
199
- let retry_policy =
200
- ExponentialBackoff :: builder ( ) . build_with_max_retries ( self . retries ) ;
201
- let retry_strategy = RetryTransientMiddleware :: new_with_policy ( retry_policy) ;
202
- let client = client. with ( retry_strategy) ;
203
-
204
- // Initialize the authentication middleware to set headers.
205
- let client =
206
- client. with ( AuthMiddleware :: new ( ) . with_keyring ( self . keyring . to_provider ( ) ) ) ;
207
-
208
- client. build ( )
192
+ for middleware in & self . middleware_stack {
193
+ client = client. with_arc ( middleware. clone ( ) ) ;
209
194
}
195
+ client. build ( )
210
196
}
211
197
Connectivity :: Offline => reqwest_middleware:: ClientBuilder :: new ( client. clone ( ) )
212
198
. with ( OfflineMiddleware )
0 commit comments