pub struct Dynamic<T> { /* private fields */ }Expand description
A configuration owned by a value rather than a type.
Construct one from a Builder carrying the sources; everything the
type-level surface does through generated statics happens here through
the instance’s own storage. Two instances of the same T are fully
independent: separate snapshots, separate reload hooks, separate
watchers, separate caches if configured.
Cloning is deliberately absent: a Dynamic is an owner — share one
behind an Arc when several places read it, which is also what keeps
“who stops the watcher” a question with one answer.
Implementations§
Source§impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
Sourcepub fn new(builder: Builder<T>) -> Self
pub fn new(builder: Builder<T>) -> Self
Wraps builder around storage this instance owns.
The builder’s sources, cache and validation hook all apply
unchanged; an installer the builder already carried (a generated
builder()’s static cell) is replaced by this instance’s own.
Sourcepub fn init(&self) -> Result<(), Error>
pub fn init(&self) -> Result<(), Error>
Loads and installs as this instance’s snapshot.
The same lifecycle as a type’s init(): validation runs before
anything installs, a configured cache is written after a clean
load and recovered from when the sources will not load.
§Errors
Whatever the load reports: a file that will not parse, a missing required value, a validation refusal with no cache to fall back on.
Sourcepub fn init_and_current(&self) -> Result<Arc<T>, Error>
pub fn init_and_current(&self) -> Result<Arc<T>, Error>
init, handing back the snapshot it installed.
Worth more here than on the type-level surface: an instance’s
current is an Option — nothing can panic with a
type’s name in it — so the split form ends in an expect that this
removes. What comes back is this call’s snapshot, not whatever a
reload made current a moment later.
§Errors
Exactly init’s.
Sourcepub fn current(&self) -> Option<Arc<T>>
pub fn current(&self) -> Option<Arc<T>>
The installed snapshot, if init has succeeded.
One atomic load, no lock — cheap enough per request, but take it
once per request and reuse the Arc, or a reload landing
mid-request shows one request two configurations. None before the
first successful install: an instance has no place to panic with
the type’s name in it, so absence is an answer rather than an
accident.
Sourcepub fn generation(&self) -> u64
pub fn generation(&self) -> u64
Installs since this instance was created; zero before the first.
Monotonic, and the number a reload hook should read when it needs a
total order — on_reload does not define one
across overlapping reloads.
Sourcepub fn meta(&self) -> Option<SnapshotMeta>
pub fn meta(&self) -> Option<SnapshotMeta>
What is true of the installed snapshot, or None before the first.
For operators — which generation is live, how long ago it landed —
and deliberately off the read path: current does
not consult it, so the value and its metadata are two loads that a
reload landing between them leaves one install apart. See
SnapshotMeta.
Sourcepub fn on_reload(&self, hook: impl Fn(&Arc<T>, &Arc<T>) + Send + Sync + 'static)
pub fn on_reload(&self, hook: impl Fn(&Arc<T>, &Arc<T>) + Send + Sync + 'static)
Runs hook after every later install, for the instance’s lifetime.
The same contract as the type-level on_reload: called with the
outgoing and incoming snapshots, on whichever thread performed the
reload — compare, then signal the subsystem that owns the resource.
§Concurrent reloads
Each call sees a consistent (previous, current) pair: both were
installed, and current was installed after previous.
The order of calls is not defined when two reloads overlap. Two
hooks may observe the same pair, and one hook may see (A, B) after
another saw (B, C). A hook that needs a total order should read
generation — which is monotonic — rather than
infer one from its arguments.
Reloads are not serialised against each other on purpose: a lock held across user callbacks would let one slow hook delay every reader, and a hook that blocked would then block reloads.
Sourcepub fn on_reload_scoped(
&self,
hook: impl Fn(&Arc<T>, &Arc<T>) + Send + Sync + 'static,
) -> HookGuard<T>
pub fn on_reload_scoped( &self, hook: impl Fn(&Arc<T>, &Arc<T>) + Send + Sync + 'static, ) -> HookGuard<T>
on_reload, until the returned guard drops.
The same concurrency contract: a consistent pair every call, in no defined order across overlapping reloads.
Sourcepub fn on_reload_with(
&self,
hook: impl Fn(&ReloadEvent<T>) + Send + Sync + 'static,
)
pub fn on_reload_with( &self, hook: impl Fn(&ReloadEvent<T>) + Send + Sync + 'static, )
on_reload, told why.
The callback receives a ReloadEvent: both
snapshots, the ReloadReason, and the
install’s SnapshotMeta. Same list, same
registration order, same panic isolation as the pair form — and it
fires for the first install too, with previous: None, which
the pair form has nowhere to say.
Sourcepub fn on_reload_with_scoped(
&self,
hook: impl Fn(&ReloadEvent<T>) + Send + Sync + 'static,
) -> HookGuard<T>
pub fn on_reload_with_scoped( &self, hook: impl Fn(&ReloadEvent<T>) + Send + Sync + 'static, ) -> HookGuard<T>
on_reload_with, until the returned guard
drops.
Sourcepub fn status(&self) -> ConfigStatus
pub fn status(&self) -> ConfigStatus
What is true of this instance right now: generation, when it landed, why, and how the reloads since have gone.
A handful of atomic loads and no I/O — no source is re-read —
so an exporter can call it per scrape. See
ConfigStatus for what it carries and, as
deliberately, what it does not.
Source§impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
Sourcepub fn watch(&self, debounce: Duration) -> Result<WatchHandle>
Available on crate feature watch only.
pub fn watch(&self, debounce: Duration) -> Result<WatchHandle>
watch only.Reloads on file changes until the returned handle is dropped.
The same watcher as everything else — same debounce, same
directory-level watches — registered under this instance rather
than the type: two instances of one T watch side by side, and a
second watch on the same instance is AlreadyExists, exactly the
one-watcher-per-owner contract the type-level surface has.
§Errors
As the builder’s watch: no watchable directory, a backend that
cannot start, or this instance already being watched.
Sourcepub fn watch_with(
&self,
debounce: Duration,
mode: WatchMode,
) -> Result<WatchHandle>
Available on crate feature watch only.
pub fn watch_with( &self, debounce: Duration, mode: WatchMode, ) -> Result<WatchHandle>
watch only.Source§impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
impl<T: DeserializeOwned + Send + Sync + 'static> Dynamic<T>
Sourcepub fn changes(&self) -> Changes<T>
Available on crate feature async only.
pub fn changes(&self) -> Changes<T>
async only.A handle woken by every later install of this instance.
The same contract as the type-level changes(): the snapshot
current at this call counts as already seen, and a handle taken
before init sees the first install as its first
change — “wake me when configuration exists”. The handle keeps the
instance’s storage alive, so it outliving the Dynamic is safe
rather than subtle.
Sourcepub async fn load_async(&self) -> Result<T, Error>
Available on crate feature async only.
pub async fn load_async(&self) -> Result<T, Error>
async only.Sourcepub async fn init_async(&self) -> Result<(), Error>
Available on crate feature async only.
pub async fn init_async(&self) -> Result<(), Error>
async only.Sourcepub async fn init_and_current_async(&self) -> Result<Arc<T>, Error>
Available on crate feature async only.
pub async fn init_and_current_async(&self) -> Result<Arc<T>, Error>
async only.Trait Implementations§
Auto Trait Implementations§
impl<T> !Freeze for Dynamic<T>
impl<T> !RefUnwindSafe for Dynamic<T>
impl<T> !UnwindSafe for Dynamic<T>
impl<T> Send for Dynamic<T>
impl<T> Sync for Dynamic<T>
impl<T> Unpin for Dynamic<T>
impl<T> UnsafeUnpin for Dynamic<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
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 bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
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>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
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 rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
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 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.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
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);