Skip to main content

Function

Trait Function 

Source
pub trait Function:
    Send
    + Sync
    + 'static {
    type Config: FunctionConfig;

    // Required method
    fn call(
        &self,
        ctx: &mut Ctx<'_>,
        cfg: &Self::Config,
    ) -> impl Future<Output = Result<Outcome>> + Send;

    // Provided methods
    fn spec(&self) -> FunctionSpec { ... }
    fn prepare(
        &self,
        _cfg: &mut Self::Config,
        _p: &Prepare<'_>,
    ) -> Result<(), Vec<Issue>> { ... }
}
Expand description

A host function: a typed config compiled once at build, and a call per task run.

call returns a Send future, so an implementation may be written with async fn. testing::call runs one call of it outside any workflow:

use dataflow_rs::datavalue::OwnedDataValue;
use dataflow_rs::expr::Output;
use dataflow_rs::function::{FunctionConfig, FunctionSpec, testing};
use dataflow_rs::{Ctx, Expr, Function, Outcome, Registry, Result};
use serde_json::json;

#[derive(FunctionConfig)]
struct FetchConfig {
    url: Expr<String>,
    #[output(default = "data.response")]
    output: Output,
}

struct Fetch;

impl Function for Fetch {
    type Config = FetchConfig;

    fn spec(&self) -> FunctionSpec {
        FunctionSpec::default().with_category("io")
    }

    async fn call(&self, ctx: &mut Ctx<'_>, cfg: &FetchConfig) -> Result<Outcome> {
        let url = ctx.eval(&cfg.url)?;
        // A real fetch awaits its response here.
        let response = OwnedDataValue::from(&json!({"url": &*url, "status": 200}));
        ctx.emit(&cfg.output, response)?;
        Ok(Outcome::Ok)
    }
}

let mut registry = Registry::default();
registry.register("fetch", Fetch);

let called = testing::call(Fetch, json!({"url": "https://example.com"})).await;
assert_eq!(called.outcome.unwrap(), Outcome::Ok);
let status = called.message.context().get(&"data.response.status".parse().unwrap());
assert_eq!(status, Some(&OwnedDataValue::from(&json!(200))));

Required Associated Types§

Source

type Config: FunctionConfig

The function’s input, compiled at build.

Required Methods§

Source

fn call( &self, ctx: &mut Ctx<'_>, cfg: &Self::Config, ) -> impl Future<Output = Result<Outcome>> + Send

Runs one call.

Provided Methods§

Source

fn spec(&self) -> FunctionSpec

What the function says about itself, for tooling. Called once, when it is registered.

Source

fn prepare( &self, _cfg: &mut Self::Config, _p: &Prepare<'_>, ) -> Result<(), Vec<Issue>>

Checks or completes a compiled config at build, with what the config alone cannot know. It runs only when the config compiled.

Issue paths are relative to the config. The compiler prefixes the task’s function.input path and stamps the step, and a Rejected issue fails the task’s compile.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§