Struct smart_config::de::Secret

source ·
pub struct Secret<De>(pub De);
Expand description

Deserializer for arbitrary secret params. Will set the corresponding flag for ParamMetadata, making raw param value hidden in the debug output etc.

Can be used by placing #[serde(secret)] on the param.

Important. The deserializer does not hide the deserialized value of the param! You are responsible for doing it by selecting an appropriate param type (e.g., one that zeroizes its contents on drop).

§Examples

use secrecy::{ExposeSecret, ExposeSecretMut, SecretBox};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use smart_config::{de::Serde, testing, DescribeConfig, DeserializeConfig};

// It is generally a good idea to wrap a secret into a `SecretBox`
// so that it is zeroized on drop and has an opaque `Debug` representation.
#[derive(Debug)]
struct NumSecret(SecretBox<u64>);

impl Serialize for NumSecret {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // Serialize the underlying secret
        self.0.expose_secret().serialize(serializer)
    }
}

impl<'de> serde::Deserialize<'de> for NumSecret {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // Deserialize a `u64` and wrap it into a secret.
        let mut secret = SecretBox::default();
        *secret.expose_secret_mut() = u64::deserialize(deserializer)?;
        Ok(Self(secret))
    }
}

#[derive(DescribeConfig, DeserializeConfig)]
struct TestConfig {
    // Secret values must be deserializable from a string
    // because all secrets are strings. Because of type coercion, a `u64` deserializer
    // will work correctly if supplied with a string, which we express
    // through `Serde![]` args.
    #[config(secret, with = Serde![int, str])]
    secret: NumSecret,
}

let input = smart_config::config!("secret": "123");
let config: TestConfig = testing::test(input)?;
assert_eq!(*config.secret.0.expose_secret(), 123);

Tuple Fields§

§0: De

Trait Implementations§

source§

impl<De: Debug> Debug for Secret<De>

source§

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

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

impl<T, De> DeserializeParam<T> for Secret<De>
where De: DeserializeParam<T>,

source§

const EXPECTING: BasicTypes = _

Describes which parameter this deserializer is expecting.
source§

fn describe(&self, description: &mut TypeDescription)

Additional info about the deserialized type, e.g., extended description.
source§

fn deserialize_param( &self, ctx: DeserializeContext<'_>, param: &'static ParamMetadata, ) -> Result<T, ErrorWithOrigin>

Performs deserialization given the context and param metadata. Read more
source§

fn serialize_param(&self, param: &T) -> Value

Serializes the provided parameter to the JSON model. Read more

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

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

§

impl<De> UnwindSafe for Secret<De>
where De: 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> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<T, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more