@@ -19,23 +19,49 @@ use futures_util::TryFutureExt;
19
19
use http:: StatusCode ;
20
20
#[ cfg( feature = "reqwest" ) ]
21
21
use reqwest:: { Client as HttpClient , Response as HttpResponse } ;
22
+ use std:: collections:: { BTreeMap , HashMap } ;
23
+ use std:: fmt:: { self , Debug , Formatter } ;
24
+ use std:: sync:: Arc ;
22
25
#[ cfg( feature = "surf" ) ]
23
26
use surf:: { Client as HttpClient , Response as HttpResponse } ;
24
27
25
28
use crate :: query:: QueryType ;
26
29
use crate :: Error ;
27
30
use crate :: Query ;
28
- use std:: collections:: HashMap ;
29
- use std:: sync:: Arc ;
30
31
31
- #[ derive( Clone , Debug ) ]
32
+ #[ derive( Clone ) ]
32
33
/// Internal Representation of a Client
33
34
pub struct Client {
34
35
pub ( crate ) url : Arc < String > ,
35
36
pub ( crate ) parameters : Arc < HashMap < & ' static str , String > > ,
36
37
pub ( crate ) client : HttpClient ,
37
38
}
38
39
40
+ struct RedactPassword < ' a > ( & ' a HashMap < & ' static str , String > ) ;
41
+
42
+ impl < ' a > Debug for RedactPassword < ' a > {
43
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
44
+ let entries = self
45
+ . 0
46
+ . iter ( )
47
+ . map ( |( k, v) | match * k {
48
+ "p" => ( * k, "<redacted>" ) ,
49
+ _ => ( * k, v. as_str ( ) ) ,
50
+ } )
51
+ . collect :: < BTreeMap < & ' static str , & str > > ( ) ;
52
+ f. debug_map ( ) . entries ( entries. into_iter ( ) ) . finish ( )
53
+ }
54
+ }
55
+
56
+ impl Debug for Client {
57
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
58
+ f. debug_struct ( "Client" )
59
+ . field ( "url" , & self . url )
60
+ . field ( "parameters" , & RedactPassword ( & self . parameters ) )
61
+ . finish_non_exhaustive ( )
62
+ }
63
+ }
64
+
39
65
impl Client {
40
66
/// Instantiates a new [`Client`](crate::Client)
41
67
///
@@ -260,6 +286,25 @@ pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
260
286
#[ cfg( test) ]
261
287
mod tests {
262
288
use super :: Client ;
289
+ use indoc:: indoc;
290
+
291
+ #[ test]
292
+ fn test_client_debug_redacted_password ( ) {
293
+ let client = Client :: new ( "https://localhost:8086" , "db" ) . with_auth ( "user" , "pass" ) ;
294
+ let actual = format ! ( "{:#?}" , client) ;
295
+ let expected = indoc ! { r#"
296
+ Client {
297
+ url: "https://localhost:8086",
298
+ parameters: {
299
+ "db": "db",
300
+ "p": "<redacted>",
301
+ "u": "user",
302
+ },
303
+ ..
304
+ }
305
+ "# } ;
306
+ assert_eq ! ( actual. trim( ) , expected. trim( ) ) ;
307
+ }
263
308
264
309
#[ test]
265
310
fn test_fn_database ( ) {
0 commit comments