Skip to content

Commit 87feeb3

Browse files
committed
add Secret<T> wrapper type
1 parent 247b22f commit 87feeb3

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

src/cargo/util/auth.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde::Deserialize;
1010
use std::collections::HashMap;
1111
use std::error::Error;
1212
use std::io::{Read, Write};
13+
use std::ops::Deref;
1314
use std::path::PathBuf;
1415
use std::process::{Command, Stdio};
1516
use time::format_description::well_known::Rfc3339;
@@ -21,6 +22,70 @@ use crate::ops::RegistryCredentialConfig;
2122

2223
use 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`.
2590
pub fn registry_credential_config(
2691
config: &Config,

0 commit comments

Comments
 (0)