Derive Macro async_injector::Provider

source ·
#[derive(Provider)]
{
    // Attributes available to this derive:
    #[dependency]
}
Expand description

Helper derive to implement a “provider”.

The Provider derive can only be used on structs. Each field designates a value that must either be injected, or provided during construction.

use async_injector::Provider;
use serde::Serialize;

#[derive(Serialize)]
enum Tag {
    Table,
    Url,
}

#[derive(Provider)]
struct Deps {
    fixed: String,
    #[dependency(optional, tag = Tag::Table)]
    table: Option<String>,
    #[dependency(tag = Tag::Url)]
    url: String,
    #[dependency]
    connection_limit: u32,
}

This generates another struct named DepsProvider, with the following api:

use async_injector::{Error, Injector};

impl Deps {
    /// Construct a new provider.
    async fn provider(injector: &Injector, fixed: String) -> Result<DepsProvider, Error>
}

struct DepsProvider {
    /* private fields */
}

impl DepsProvider {
    /// Try to construct the current value. Returns [None] unless all
    /// required dependencies are available.
    fn build(&mut self) -> Option<Deps>

    /// Wait until we can successfully build the complete provided
    /// value.
    async fn wait(&mut self) -> Deps

    /// Wait until the provided value has changed. Either some
    /// dependencies are no longer available at which it returns `None`,
    /// or all dependencies are available after which we return the
    /// build value.
    async fn wait_for_update(&mut self) -> Option<Deps>
}

The provider associated function takes the reference to an injector as its first argument and any fields which are not marked as a #[dependency]. These are called fixed fields.


The #[dependency] field attribute

The #[dependency] attribute can be used to mark fields which need to be injected. It takes an optional #[dependency(tag = ...)], which allows you to specify the tag to use when constructing the injected Key.

use async_injector::Provider;
use serde::Serialize;

#[derive(Serialize)]
enum Tag {
    First,
}

#[derive(Provider)]
struct Params {
    #[dependency(tag = Tag::First)]
    tagged: String,
    #[dependency]
    number: u32,
}

Optional fields use the Option type and must be marked with the optional meta attribute.

use async_injector::Provider;

#[derive(Provider)]
struct Params {
    #[dependency(optional)]
    table: Option<String>,
}