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 theToFuture
, 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 anasync
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
impl<F, Fut, R, II, SF> Transformation<R, II, SF> for ToFutureUnconfigured<F> where
F: FnMut(R) -> Fut,
Fut: Future<Output = ()> + 'static,
impl<F, Fut, R, II, SF> Transformation<R, II, SF> for ToFutureUnconfigured<F> where
F: FnMut(R) -> Fut,
Fut: Future<Output = ()> + 'static,
type OutputResource = Fut
type OutputResource = Fut
The type of resource after the transformation.
type OutputInstaller = FutureInstaller
type OutputInstaller = FutureInstaller
The type of installer after the transformation. Read more
Creates the installer. Read more