@@ -19,23 +19,49 @@ use futures_util::TryFutureExt;
1919use http:: StatusCode ;
2020#[ cfg( feature = "reqwest" ) ]
2121use 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 ;
2225#[ cfg( feature = "surf" ) ]
2326use surf:: { Client as HttpClient , Response as HttpResponse } ;
2427
2528use crate :: query:: QueryType ;
2629use crate :: Error ;
2730use crate :: Query ;
28- use std:: collections:: HashMap ;
29- use std:: sync:: Arc ;
3031
31- #[ derive( Clone , Debug ) ]
32+ #[ derive( Clone ) ]
3233/// Internal Representation of a Client
3334pub struct Client {
3435 pub ( crate ) url : Arc < String > ,
3536 pub ( crate ) parameters : Arc < HashMap < & ' static str , String > > ,
3637 pub ( crate ) client : HttpClient ,
3738}
3839
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+
3965impl Client {
4066 /// Instantiates a new [`Client`](crate::Client)
4167 ///
@@ -260,6 +286,25 @@ pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
260286#[ cfg( test) ]
261287mod tests {
262288 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+ }
263308
264309 #[ test]
265310 fn test_fn_database ( ) {
0 commit comments