@@ -10,6 +10,7 @@ use serde::Deserialize;
1010use std:: collections:: HashMap ;
1111use std:: error:: Error ;
1212use std:: io:: { Read , Write } ;
13+ use std:: ops:: Deref ;
1314use std:: path:: PathBuf ;
1415use std:: process:: { Command , Stdio } ;
1516use time:: format_description:: well_known:: Rfc3339 ;
@@ -21,6 +22,70 @@ use crate::ops::RegistryCredentialConfig;
2122
2223use super :: config:: CredentialCacheValue ;
2324
25+ /// A wrapper for values that should not be printed.
26+ ///
27+ /// This type does not implement `Display`, and has a `Debug` impl that hides
28+ /// the contained value.
29+ #[ derive( Clone , PartialEq , Eq ) ]
30+ pub struct Secret < T > {
31+ inner : T ,
32+ }
33+
34+ impl < T > Secret < T > {
35+ /// Converts a `Secret<T>` to a `Secret<&T::Target>`.
36+ ///
37+ /// For example, this can be used to convert from `&Secret<String>` to
38+ /// `Secret<&str>`.
39+ pub fn as_deref ( & self ) -> Secret < & <T as Deref >:: Target >
40+ where
41+ T : Deref ,
42+ {
43+ Secret :: from ( self . inner . deref ( ) )
44+ }
45+
46+ pub fn map < U , F > ( self , f : F ) -> Secret < U >
47+ where
48+ F : FnOnce ( T ) -> U ,
49+ {
50+ Secret :: from ( f ( self . inner ) )
51+ }
52+
53+ fn into_inner ( self ) -> T {
54+ self . inner
55+ }
56+ }
57+
58+ impl < T : ToOwned + ?Sized > Secret < & T > {
59+ /// Converts a `Secret` containing a borrowed type to a `Secret` containing the
60+ /// corresponding owned type.
61+ ///
62+ /// For example, this can be used to convert from `Secret<&str>` to
63+ /// `Secret<String>`.
64+ pub fn owned ( & self ) -> Secret < <T as ToOwned >:: Owned > {
65+ Secret :: from ( self . inner . to_owned ( ) )
66+ }
67+ }
68+
69+ impl < T : AsRef < str > > Secret < T > {
70+ pub fn is_empty ( & self ) -> bool {
71+ self . inner . as_ref ( ) . is_empty ( )
72+ }
73+ }
74+
75+ impl < T > From < T > for Secret < T > {
76+ fn from ( inner : T ) -> Self {
77+ Self { inner }
78+ }
79+ }
80+
81+ impl < T > fmt:: Debug for Secret < T > {
82+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
83+ f. debug_struct ( "Secret" )
84+ . field ( "inner" , & "REDACTED" )
85+ . finish ( )
86+ }
87+ }
88+
2489/// Get the credential configuration for a `SourceId`.
2590pub fn registry_credential_config (
2691 config : & Config ,
0 commit comments