Struct spirit_tokio::handlers::ToFutureUnconfigured[][src]

pub struct ToFutureUnconfigured<F>(pub F);
Expand description

A Transformation to take a resource, turn it into a future and install it.

Unlike ToFuture, this one doesn’t pass the configuration to the closure.

Examples

This is mostly the same example as the one at the crate root, but done slightly differently. The future is created later on, during the transformation phase. While a little bit more verbose here, this comes with two advantages:

  • Works with already provided fragments, like the network primitives in net. In that case you might want to prefer the ToFuture, as it also gives access to the original configuration fragment, including any extra configuration for the future.
  • The future can be an arbitrary anonymous/unnameable type (eg. impl Future or an async function), there’s no need for boxing. This might have slight positive effect on performance.
use std::time::Duration;

use err_context::AnyError;
use serde::{Deserialize, Serialize};
use spirit::{Empty, Pipeline, Spirit};
use spirit::prelude::*;
use spirit::fragment::driver::CacheEq;
use spirit_tokio::handlers::ToFutureUnconfigured;
use structdoc::StructDoc;

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, StructDoc)]
#[serde(default)]
struct MsgCfg {
    /// A message to print now and then.
    msg: String,
    /// Time between printing the message.
    interval: Duration,
}

impl MsgCfg {
    async fn run(self) {
        loop {
            println!("{}", self.msg);
            tokio::time::sleep(self.interval).await;
        }
    }
}

impl Default for MsgCfg {
    fn default() -> Self {
        MsgCfg {
            msg: "Hello".to_owned(),
            interval: Duration::from_secs(1),
        }
    }
}

spirit::simple_fragment! {
    impl Fragment for MsgCfg {
        type Driver = CacheEq<MsgCfg>;
        // We simply send the configuration forward
        type Resource = Self;
        type Installer = ();
        fn create(&self, _: &'static str) -> Result<Self::Resource, AnyError> {
            Ok(self.clone())
        }
    }
}

/// An application.
#[derive(Default, Deserialize, Serialize, StructDoc)]
struct AppConfig {
    #[serde(flatten)]
    msg: MsgCfg,
}

impl AppConfig {
    fn msg(&self) -> &MsgCfg {
        &self.msg
    }
}

fn main() {
    Spirit::<Empty, AppConfig>::new()
        // Will install and possibly cancel and replace the future if the config changes.
        .with(
            Pipeline::new("Msg")
                .extract_cfg(AppConfig::msg)
                // This thing turns it into the future and sets how to install it.
                .transform(ToFutureUnconfigured(MsgCfg::run))
        )
        // Just an empty body here.
        .run(|spirit| {
            // Usually, one would terminate by CTRL+C, but we terminate from here to make sure
            // the example finishes.
            spirit.terminate();
            Ok(())
        })
}

Tuple Fields

0: F

Trait Implementations

The type of resource after the transformation.

The type of installer after the transformation. Read more

Creates the installer. Read more

Transforms one instance of the resource. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

Turns self into the result.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.