rocket_db_pools::figment

Trait Provider

Source
pub trait Provider {
    // Required methods
    fn metadata(&self) -> Metadata;
    fn data(&self) -> Result<BTreeMap<Profile, BTreeMap<String, Value>>, Error>;

    // Provided method
    fn profile(&self) -> Option<Profile> { ... }
}
Expand description

Trait implemented by configuration source providers.

For an overview of built-in providers, see the top-level docs.

§Overview

A Provider reads from a source to provide configuration data for Figments (Provider::data()). A Provider also provides Metadata to identify the source of its configuration data (Provider::metadata()). A provider may also optionally set a Profile for the Figment it is merged (but not joined) into by implementing Provider::profile().

§Nesting

A Provider meant to be consumed externally should allow for optional nesting when sensible. The general pattern is to allow a Profile to be specified. If one is not, read the configuration data as a Map<Profile, Dict>, thus using the top-level keys as profiles. If one is specified, read the data as Dict and Profile::collect() into the specified profile.

§Example

Implementing a Provider requires implementing methods that provide both of these pieces of data. The first, Provider::metadata() identifies the provider’s configuration sources, if any, and allows the provider to customize how paths to keys are interpolated. The second, Provider::data(), actually reads the configuration and returns the data.

As an example, consider a provider that reads configuration from a networked store at some Url. A Provider implementation for such a provider may resemble the following:

use figment::{Provider, Metadata, Profile, Error, value::{Map, Dict}};

/// A provider that fetches its data from a given URL.
struct NetProvider {
    /// The profile to emit data to if nesting is disabled.
    profile: Option<Profile>,
    /// The url to fetch data from.
    url: Url
};

impl Provider for NetProvider {
    /// Returns metadata with kind `Network`, custom source `self.url`,
    /// and interpolator that returns a URL of `url/a/b/c` for key `a.b.c`.
    fn metadata(&self) -> Metadata {
        let url = self.url.clone();
        Metadata::named("Network")
            .source(self.url.as_str())
            .interpolater(move |profile, keys| match profile.is_custom() {
                true => format!("{}/{}/{}", url, profile, keys.join("/")),
                false => format!("{}/{}", url, keys.join("/")),
            })
    }

    /// Fetches the data from `self.url`. Note that `Dict`, `Map`, and
    /// `Profile` are `Deserialize`, so we can deserialized to them.
    fn data(&self) -> Result<Map<Profile, Dict>, Error> {
        fn fetch<'a, T: Deserialize<'a>>(url: &Url) -> Result<T, Error> {
            /* fetch from the network, deserialize into `T` */
        }

        match &self.profile {
            // Don't nest: `fetch` into a `Dict`.
            Some(profile) => Ok(profile.collect(fetch(&self.url)?)),
            // Nest: `fetch` into a `Map<Profile, Dict>`.
            None => fetch(&self.url),
        }
    }
}

Required Methods§

Source

fn metadata(&self) -> Metadata

Returns the Metadata for this provider, identifying itself and its configuration sources.

Source

fn data(&self) -> Result<BTreeMap<Profile, BTreeMap<String, Value>>, Error>

Returns the configuration data.

Provided Methods§

Source

fn profile(&self) -> Option<Profile>

Optionally returns a profile to set on the Figment this provider is merged into. The profile is only set if self is merged.

Implementations on Foreign Types§

Source§

impl Provider for Config

Source§

impl<K, V> Provider for (K, V)
where K: AsRef<str>, V: Serialize,

This is exactly equivalent to Serialized::global(K, V).

Source§

impl<T> Provider for &T
where T: Provider,

This is exactly <T as Provider>.

Implementors§

Source§

impl Provider for Env

Source§

impl Provider for Figment

Source§

impl<F> Provider for Data<F>
where F: Format,

Source§

impl<T> Provider for Serialized<T>
where T: Serialize,