Skip to main content

Value

Enum Value 

Source
pub enum Value {
    Null,
    Bool(bool),
    Integer(i128),
    Float(f64),
    String(String),
    Array(Vec<Value>),
    Table(BTreeMap<String, Value>),
}
Expand description

One resolved configuration value, owned.

What Snapshot::to_value returns. This is configuration handover, not a diagnostic: real values, secrets included, exactly like deserializing into a struct — the paths-only rule governs what this crate prints, not what it hands the program.

Which is why Debug is hand-written and shape-only: the same data sits inside Snapshot, whose Debug prints keys and never values, and {:?} in a log line is exactly how resolved secrets leak. Read values through the enum; print them on purpose or not at all.

There is deliberately no Display. A schemaless configuration has no #[config(secret)] to derive a redaction list from, so a type that rendered itself into {} would put a password wherever a program formats a value it did not inspect — and it would do it in the one shape (format!, write!, a template) where nothing looks like a decision. The ways out are all explicit: the accessors, get_as, render for a document, and Serialize for a serializer the caller chose.

Variants§

§

Null

An explicit null (or unit) in a source.

§

Bool(bool)

A boolean.

§

Integer(i128)

Any integer a source can express.

i128, so every i64 and u64 fits without a sign decision at this boundary. The one unrepresentable case — a u128 above i128::MAX — arrives as Value::Float, lossily; a configuration value up there is measuring something no unit this crate knows about.

§

Float(f64)

A floating-point number.

§

String(String)

A string; a single character in a source arrives as one too.

§

Array(Vec<Value>)

A sequence.

§

Table(BTreeMap<String, Value>)

A table, keyed by field name.

Implementations§

Source§

impl Value

Source

pub fn get(&self, path: &str) -> Option<&Value>

The value at a dotted path below this one, if every step exists.

Steps are table keys; anything else — an array, a leaf — ends the walk with None. The empty path is this value itself.

Source

pub fn get_as<T: DeserializeOwned>(&self, path: &str) -> Result<T, Error>

The value at a dotted path, deserialized into T.

The convenient door onto a schemaless configuration, and the more expensive one. get walks the tree and hands back a borrow; this walks it, rebuilds the value figment’s deserializer wants and runs serde over it — on every call. Measured against the borrowed read on the same machine in the same run (benches/read_path.rs), that is around a third again as long for a scalar, and it allocates whatever the value it hands back owns: a number, nothing; a String, one.

The bigger reason to prefer the accessors is not the nanoseconds but the Result: get_as is a conversion that can fail at every read, which is a diagnostic-grade shape. Use it where a value is read once at startup or per reload — a serde type the accessors cannot express, a Vec<String>, a struct for one sub-tree — and get plus as_i64 and friends on a request path. It is the same trade Snapshot::get makes, written down where the schemaless reader will meet it.

use dynamic_config::{Format, Value};

let document = Value::parse(r#"{"pool": {"max_size": 32}}"#, Format::Json).unwrap();

assert_eq!(document.get_as::<u16>("pool.max_size").unwrap(), 32);
§Errors

ErrorKind::Missing when nothing supplies path — including a path that walks through a scalar — and ErrorKind::Type when what is there cannot become T. The message names the path and the kind of thing that was there, never the value.

Source

pub fn as_bool(&self) -> Option<bool>

The boolean here, or None if this is anything else.

Source

pub fn as_integer(&self) -> Option<i128>

The integer here, at the width this crate stores it in.

None for a float, even one that is a whole number: which of the two a source wrote is part of the configuration here, and Value::Integer’s i128 is what makes that distinction free of a sign decision.

Source

pub fn as_i64(&self) -> Option<i64>

The integer here as an i64, or None if it is not one or does not fit.

Narrowing rather than saturating: a port number that does not fit is a configuration mistake, and a clamped one is that mistake made silent.

Source

pub fn as_u64(&self) -> Option<u64>

The integer here as a u64, or None if it is not one, is negative, or does not fit.

Source

pub fn as_float(&self) -> Option<f64>

The float here, or None if this is anything else — an integer included, for the reason as_integer gives.

Source

pub fn as_str(&self) -> Option<&str>

The string here, borrowed, or None if this is anything else.

Source

pub fn as_array(&self) -> Option<&[Value]>

The sequence here, borrowed, or None if this is anything else.

Source

pub fn as_table(&self) -> Option<&BTreeMap<String, Value>>

The table here, borrowed, or None if this is anything else.

Source

pub fn leaf_paths(&self) -> Vec<String>

The dotted path of every leaf, in order.

What a schemaless configuration has instead of a field list: the keys that are actually there, learned at runtime. The same walk Snapshot::leaf_paths performs, on the tree a reader already holds — an array is a leaf, because its elements are values rather than configuration keys, and so is an empty table, which would otherwise vanish from the listing.

Paths carry no values, so this is the one listing of a resolved configuration that is safe to log.

A tree that is not a table has no paths: a document has named keys at its root.

Source

pub fn parse(text: &str, format: Format) -> Result<Self, Error>

Parses one format document into a tree.

The way in to the parsing this crate already owns, for code that has documents to combine before the loader sees them: a store crate that reads several keys under a prefix, a tool that folds a fragment directory into one file. Without it the only way to merge two documents outside this crate is to depend on serde_json, toml and serde_yaml directly and reimplement what the json / toml / yaml features are already compiling.

No section mapping is applied: the result is the document as written, top-level keys and all. Sections are what the loader does with a document, and a merge happens below that line.

use dynamic_config::{Format, Value};

let mut document = Value::parse(r#"{"db": {"host": "a"}}"#, Format::Json).unwrap();
document.merge(Value::parse(r#"{"db": {"port": 5432}}"#, Format::Json).unwrap());

assert_eq!(document.get("db.host"), Some(&Value::String("a".into())));
assert_eq!(document.get("db.port"), Some(&Value::Integer(5432)));
§Errors

ErrorKind::Parse if the text is not a valid format document, and ErrorKind::Backend if this build has that format’s feature off. The message is stripped the same way every other backend failure here is — the key and the kind of thing that was there, never the value.

Source

pub fn merge(&mut self, other: Value)

Merges other over this value: later wins, tables deep.

The rule the crate already teaches for files, applied to two trees. Where both sides have a table the merge descends into it; anywhere else other replaces what was there, arrays included — a later document supplying tags = ["b"] means those tags and not the earlier ones, which is what every layer in this crate already means by it.

Source

pub fn overlapping_paths(&self, other: &Value) -> Vec<String>

Every leaf path both trees supply — what merge would silently resolve.

For the caller whose documents are meant to be disjoint: keys read from a prefix are sections nobody intended to overlap, so an overlap there is a deployment bug worth an error rather than a merge. Paths in sorted order, and paths only — this is a diagnostic, so it names what collided and never what either side held.

A path where both sides hold a table is not a collision; the tables merge. A path where either side holds an array or a scalar is.

Source

pub fn render(&self, format: Format) -> Result<String, Error>

Renders this tree as the text of a format document.

The way back out, so a merged tree can be handed to something that takes text — Fetched::new, a file, a socket.

§Errors

ErrorKind::Backend if this build has that format’s feature off, and ErrorKind::Type if the tree is not a table — a document has named keys at its root — or holds something the format cannot express, such as a null in TOML.

Trait Implementations§

Source§

impl Clone for Value

Source§

fn clone(&self) -> Value

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Value

Source§

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

Shape and keys, never values — the line every diagnostic in this crate holds, held here too because to_value hands over the same secret-bearing data Snapshot guards.

Source§

impl<'de> Deserialize<'de> for Value

The impl that makes a configuration with no struct behind it possible.

DeserializeOwned is the only bound the engine puts on a configuration type, so this one line is what turns Dynamic<Value>, Builder::values and load::<Value> from “would not compile” into the schemaless shape — with layering, watching, the last-known-good cache and the reload hooks all working unchanged, because none of them ever knew what T was.

Deliberately deserialize_any: a configuration value is whatever the source said it was, which is the one place in serde where self-describing is the right answer. The two numeric edges match the walk in from the resolved tree exactly — every integer widens to i128, and the one unrepresentable case (a u128 above i128::MAX) arrives as a float — so a value that reaches this type through serde and one that reaches it by walking the resolved tree are the same value.

Source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Hash for Value

Hand-written because f64 is not Hash, and because what a fingerprint wants from a float is not what arithmetic wants: hashing through f64::to_bits makes -0.0 and 0.0 hash differently, which is right here — they are different bytes in the file, and the cache’s question is “is this the same document”, not “is this the same number”.

That is also why this is deliberately not consistent with PartialEq in the two places IEEE 754 is not: -0.0 == 0.0 while their hashes differ, and no NaN equals itself while every NaN payload hashes stably. Value is not Eq for exactly those reasons, so there is no Hash/Eq contract to break.

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Value

Source§

fn eq(&self, other: &Value) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Value

The way back out through serde, for crate::save and crate::changed_paths — the two surfaces that take T: Serialize and would otherwise be the only ones a schemaless configuration could not reach.

Integers narrow exactly as the walk back out narrows them, and for the same reason: this type widens every integer on the way in so the boundary needs no sign decision, while a serializer does — toml refuses an i128 whatever the number in it is.

This is handover, like crate::Snapshot::to_value and unlike Debug: it emits real values, secrets included, because that is what serializing a configuration means. The paths-only rule governs what this crate prints, not what a caller asks it to write.

Source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Value

Auto Trait Implementations§

§

impl Freeze for Value

§

impl RefUnwindSafe for Value

§

impl Send for Value

§

impl Sync for Value

§

impl Unpin for Value

§

impl UnsafeUnpin for Value

§

impl UnwindSafe for Value

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> AnyEq for T
where T: Any + PartialEq,

Source§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

fn as_any(&self) -> &(dyn Any + 'static)

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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> Paint for T
where T: ?Sized,

Source§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
Source§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
Source§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
Source§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
Source§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling Attribute value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
Source§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
Source§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi Quirk value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
Source§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
Source§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1:

renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
Source§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the Condition value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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, 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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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