Skip to main content

Firestore

Struct Firestore 

Source
pub struct Firestore { /* private fields */ }
Expand description

A document in Firestore, as a configuration source.

Not Clone: it holds the session that caches an access token, and two clones fetching tokens separately would double the traffic.

Implementations§

Source§

impl Firestore

Source

pub fn new(project: impl Into<String>, path: impl Into<Keys>) -> Self

The document at path in project’s default database.

path is collection-then-document — config/db, or environments/prod/config/db for a nested one — or a Keys, for the several-documents form.

The document is wrapped under the section key the configuration type uses, "db" by default; change it with with_key. Several documents all land under that one key and merge, later winning.

Source

pub fn with_key(self, key: impl Into<String>) -> Self

The section key to wrap the document under.

Must match the key the config type’s builder(..) was given.

Source

pub fn with_database(self, database: impl Into<String>) -> Self

A database other than (default).

Source

pub fn with_auth(self, auth: Auth) -> Self

How to obtain an access token.

Defaults to Auth::Emulator, which sends none — right for the emulator and wrong for anything else, so a real deployment always names one.

Source

pub fn with_endpoint(self, endpoint: impl Into<String>) -> Self

A different API endpoint.

What the Firestore emulator needs: FIRESTORE_EMULATOR_HOST is 127.0.0.1:8080, and this takes http://127.0.0.1:8080.

Source

pub fn with_timeout(self, timeout: Duration) -> Self

How long a single fetch may take before it is given up on. Ten seconds by default.

The deadline for one fetch attempt, excluding retries the underlying client performs — the same sentence every store in this family answers to. ureq performs none of its own, so here the deadline is the whole story.

It covers fetching a token from the metadata server too: that request goes through the same client, and a token fetch that hangs stalls the read behind it.

Source

pub fn with_agent(self, agent: Agent) -> Self

Uses an HTTP client the program already has.

The escape hatch, and it stays one: with_tls covers a private CA and a client certificate, and everything else — a proxy, a connection pool, an option this crate has never heard of — still lives here. Setting both is refused rather than resolved; see with_tls.

Source

pub fn with_tls(self, tls: TlsConfig) -> Self

A private certificate authority, a client certificate, or both.

The same three settings, spelled the same way, in all seven store crates — and spelled as data, so nothing here names a ureq type:

let firestore = Firestore::new("my-project", "config/db")
    .with_endpoint("https://firestore.internal")
    .with_tls(TlsConfig::new().with_ca_certificate_file("/etc/ssl/private-ca.pem"));

Firestore expresses all of it: a CA from a file or from bytes, and a client certificate from either. A CA replaces the platform trust store rather than adding to it, so a deployment that needs both puts both in the file.

Against Google’s own endpoint this is rarely what you want — their certificates chain to a public authority the platform already trusts. It is for the deployments that do not go there directly: an enterprise TLS-inspecting proxy, or an emulator behind with_endpoint with a certificate of its own.

There is no way to turn verification off; TlsConfig’s own documentation argues that one.

Nothing is read here. The files are opened when the first request builds the client, so a missing CA is an error naming the path.

§With with_agent

Setting both is refused, at the first request, naming both calls. An agent already carries a complete TLS configuration, so “apply this too” has no meaning that is not a guess — and the guess that loses silently discards a CA.

Source

pub fn reporting_to(self, sink: RemoteSink) -> Self

Reports the watch loop’s failed attempts to sink.

A watch loop is the half of a store dynamic-config cannot otherwise see. RemoteSink::apply records a delivery, so a working watch keeps RemoteStatus current — but a loop whose poll is failing, whose document was deleted or whose access token was refused delivers nothing, and without this says nothing: dynamic_config_remote_up would report the last delivery rather than the last attempt, and a project that stopped answering an hour ago would look healthy until something called refresh_remote.

let sink = DbConfig::remote_sink();

Firestore::new("my-project", "config/db")
    .with_auth(Auth::metadata_server())
    .reporting_to(sink)
    .watch(&watching, Duration::from_secs(30), move |document| sink.apply(document))

One sink serves both halves, and it is taken once, where the loop is wired: a sink is Copy, and the generation it captures there is what fences a loop winding down after its source was replaced from charging its failures to the replacement.

A failure to report a failure never reaches the loop — reporting is infallible and silent — and what it moves is deliberately narrow: the failure streak and the last failure, never the fetch clock. So dynamic_config_remote_last_fetch_seconds keeps ageing while dynamic_config_remote_up goes to zero, which is the pair that says both the store is not answering and how stale what it last said has become.

A fetch needs none of this: a fetch records itself, through the Remote that performed it.

Source

pub fn watch<F>( &self, watching: &Watching, interval: Duration, on_change: F, ) -> Result<(), Error>
where F: FnMut(Fetched) -> Result<(), Error>,

Calls on_change when the document’s update time moves, checking every interval.

Firestore can push — the real-time API is a gRPC stream — and this deliberately does not use it: that would put a gRPC stack in a crate whose whole point is a plain HTTP read. Polling reads one small document and compares updateTime, which for a configuration document checked every thirty seconds is a rounding error against a project’s quota.

The current value is not delivered at startup, for the same reason a file watcher does not report an edit when it starts.

A failed check does not end the watch. stop is noticed within a quarter second whatever interval is. Surviving a failure quietly is not the same as hiding it: reporting_to hands each failed attempt to a RemoteSink, so a loop that has been failing for an hour stops reporting the store as healthy.

§Errors

If the document comes back without an updateTime — there is then nothing to compare, so every tick would find “no change” and the watch would silently never fire. Or if on_change returns an error, which ends the watch. Transport failures do not surface here; they are retried.

Trait Implementations§

Source§

impl Debug for Firestore

Source§

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

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

impl RemoteSource for Firestore

Source§

fn fetch(&self) -> Result<Fetched, Error>

Reads the current document. Read more
Source§

fn describe(&self) -> String

How to name this source in an error or a report.

Auto Trait Implementations§

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.

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