Attribute Macro subplotlib::prelude::step

source · []
#[step]
Expand description

Mark a function as a Subplot step function.

This attribute macro is used to indicate that a given function is a step which can be bound to Subplot scenario statements.

In its simplest form, you use this thusly:

#[step]
fn my_step_function(context: &mut SomeContextType, arg1: &str, arg2: &str)
{
    // Do something appropriate here.
}

Step functions must be pretty basic. For now at least they cannot be async, and they cannot be generic, take variadic arguments, be unsafe, etc.

The first argument to the step function is considered the step’s context. Anything which implements ContextElement can be used here. You can take either a &ContextType or &mut ContextType as your context. It’s likely best to take the shared borrow if you’re not altering the context at all.

If you require access to a number of context objects as part of your step function implementation, then there is the high level container ScenarioContext. You should take this high level container as a shared borrow, and then within your step function you can access other contexts as follows:

#[step]
#[context(ContextA)]
#[context(ContextB)]
fn my_step(context: &ScenarioContext, arg: &str) {
    let thingy = context.with(|ctx: &ContextA| ctx.get_thingy(), false )?;
    context.with_mut(|ctx: &mut ContextB| ctx.do_mut_thing(thingy, arg), false)?;
}

Importantly here there is the #[context(SomeContext)] attribute to tell the system that you use that context in your step function (without this, the relevant context may not be initialised for the scenario). The mechanism to then access contexts from the step function is the ScenarioContext::with and ScenarioContext::with_mut functions which allow shared, or mutable, access to scenario contexts respectively.

These functions take two arguments, the first is a closure which will be run with access to the given context and whose return value will be ultimately returned by the call to the function. The second is whether or not to defuse the poison on the context mutex. In normal steps this should be false since you want a step to fail if the context has been poisoned. However, in cleanup related step functions you probably want to defuse the poison and be careful in how you then use the contexts so that you can clean up effectively.