Secret

Struct Secret 

Source
pub struct Secret<T>(pub T);
Expand description

Use Secret<T> to wrap sensitive configuration values like passwords, API keys, and tokens. When printed or logged, the value will appear as *** instead of the actual value, preventing accidental exposure of secrets in logs or error messages.

§Examples

§Basic Usage

use tryphon::{Config, Secret};

#[derive(Debug, Config)]
struct AppConfig {
    #[env("DATABASE_PASSWORD")]
    password: Secret<String>,

    #[env("API_KEY")]
    api_key: Secret<String>,
}

let config = AppConfig::load().unwrap();

// Safe to print - secrets are masked with their hash
println!("{:?}", config);  // Shows: AppConfig { password: Secret(a3f8d2e1c9b4f6a7), api_key: Secret(b8e9c3d4a1f5b2e6) }

// Access the actual value when needed (via Deref)
let password: &String = &config.password;
assert_eq!(password, "super-secret");

§Accessing the Value

Secret<T> implements Deref<Target = T>, so you can access the wrapped value transparently:

use tryphon::Secret;

let secret = Secret("my-api-key".to_string());

// Access via deref
assert_eq!(secret.len(), 10);  // String methods work directly
assert_eq!(&*secret, "my-api-key");  // Explicit deref

§Security Note

While Secret<T> prevents accidental logging of sensitive values, it does not provide cryptographic protection. The actual value is still stored in memory in plaintext and can be accessed intentionally via dereferencing.

Tuple Fields§

§0: T

Implementations§

Source§

impl<T: Hash> Secret<T>

Source

pub fn hashed(&self) -> String

Computes a hash of the secret value for logging or comparison purposes.

Uses Rust’s standard library DefaultHasher to compute a hash of the wrapped value and returns it as a lowercase hexadecimal string. This hash is also used automatically in Debug and Display implementations.

§Use Cases
  • Logging: Identify which secret was used without exposing the value
  • Comparison: Check if two secrets have the same value without revealing it
  • Debugging: Track secret changes across application runs
§Security Note

This hash is not cryptographically secure and should not be used for:

  • Password storage (use proper password hashing like bcrypt/argon2)
  • Authentication tokens
  • Cryptographic operations

The hash algorithm (DefaultHasher) may change between Rust versions and is designed for hash tables, not security.

§Returns

A lowercase hexadecimal string representing the hash (e.g., "a3f8d2e1c9b4f6a7").

§Examples
use tryphon::Secret;

let secret1 = Secret("my-api-key".to_string());
let secret2 = Secret("my-api-key".to_string());
let secret3 = Secret("different-key".to_string());

// Same values produce same hashes
assert_eq!(secret1.hashed(), secret2.hashed());

// Different values produce different hashes
assert_ne!(secret1.hashed(), secret3.hashed());

// Hash doesn't reveal the original value
let hash = secret1.hashed();
assert!(!hash.contains("my-api-key"));

Trait Implementations§

Source§

impl<T: Clone> Clone for Secret<T>

Source§

fn clone(&self) -> Secret<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: ConfigValueDecoder> ConfigValueDecoder for Secret<T>

Source§

fn decode(raw: String) -> Result<Secret<T>, String>

Decodes a raw string value into the target type. Read more
Source§

impl<T: Hash> Debug for Secret<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for Secret<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T: Hash> Display for Secret<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Secret<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Secret<T>
where T: RefUnwindSafe,

§

impl<T> Send for Secret<T>
where T: Send,

§

impl<T> Sync for Secret<T>
where T: Sync,

§

impl<T> Unpin for Secret<T>
where T: Unpin,

§

impl<T> UnwindSafe for Secret<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.