The Itinera bookRust edition

Appendices, Appendix

Cheat sheet

Everything you declare with Itinera, in the order the book teaches it, with the chapter to read for more. After the table comes how each line is written in Rust.

What you declare

What you declare What it does Chapter
A step holds one business rule, runs once per attempt and reports an outcome 4
A step's inputs, required or optional the data a step needs, which the workflow supplies 4, 20
An outcome success, failure with a reason, or skipped 4, 16
A workflow and its steps the plan: the steps in order, each under its name 5, 6
A workflow instance and its initial data one journey's starting point 5, 24
An executor, and running an instance runs one journey at a time and returns its result, or refuses it, keeping nothing between journeys 5, 24
Reading the result and its output how the journey ended and what explains it, and its output, read typed, unless it was aborted 5, 6, 25
A contributor how a step adds data to the data bag 6
A service and its provider a tool a step asks for by a key, and the part of the workflow that supplies it, per journey or per attempt 7, 13
A reporter receives every event of a journey 8, 10
A step's own events what only the step knows, emitted as step_info, step_warning or step_error 9
A journey ID generator names each journey, for example after the order 11
A retry budget how many times a step may be tried again 12
An abnormal termination an error that escapes a running step, which spends the retry budget unless the step's line says otherwise 12
A rescue step a step that repairs the cause of a failure before the step runs once more 14
A step policy and its hooks reacts to a step's outcome, such as on step success 15
Giving a step up early on step retry or on step abnormal termination returning the lifecycle FailWorkflow 17
What a hook requests data from the step or the workflow, the step's name, the reason a step failed with, a role, a contributor 15, 17, 18, 19
A workflow policy and its hooks reacts to how the journey ended: on workflow success, on workflow failure 18
A role operations the workflow provides to policies 19
An input adapter decides where a step's inputs come from 21
A value of your own type a struct of yours, held in the data bag like any other value 21
Finishing a journey early on step success returning the lifecycle FinishWorkflow, which ends the journey as succeeded 22
Undoing a step's work when it is given up on step failure, called once the executor gives a step up by its own rule, and the hook that gives it up earlier, both calling the policy's own code 23
The asynchronous execution mode steps, hooks and services that wait without holding the thread, so journeys run at the same time 26
A step tested alone a step built from its inputs, and run with fakes of its services and recorders lending its contributor and reporter 27
A hook or an input adapter tested alone called as a method, with the data it asks for and fakes of its roles 28
A scripted run in a test, a journey in which a script says how the steps' attempts end, in place of running them 29
A fake provider and a journey's path in a test, a function in place of a workflow's provider, and the journey's outcomes and decisions as lines a test compares 30
A reporter that fails a reporter whose report fails aborts the journey with reporter failed, and receives nothing more 31
A reporter that prints every event a reporter that comes with Itinera, prints each event as it is, and never fails 32
Global metadata a key and a value every reporter of a journey receives, set by the instance before the first event or by a step while it runs 33
What only a hook can know the journey's ID, the attempt a step hook is about, and the error the step ended in 34
A key of its own, and a provider for some steps an input or a service found under a key other than its field's name; a provider attached to some steps only, handing over a service already boxed, with data saying which it is 35
An order stopped before its journey an instance not created when its journey ID can't be produced, and a journey refused when a reporter can't take its global metadata 36
The listing, and the violations of admission how a workflow is put together, read without running anything, and the mistakes caught before any journey 37
A workflow declared by hand the long form of everything above, and the violations build returns 38

In Rust

With the macros feature, which is on by default, each line of the table is written as follows. Types and attributes are imported through itinera, as in use itinera::step::{Outcome, Step, step};; the API documentation of itinera has every item.

What you declare How you write it Chapter
A step #[derive(Step)] on its struct, and #[step] on the block holding fn run(self, ...) -> Result<Outcome, Error> 4
A step's inputs a field marked #[input]; an Option<T> field is optional 4, 20
An outcome Self::succeed(), Self::fail("code"), Self::skip() or Self::skip_because("code") 4, 16
A workflow and its steps #[workflow(name = "orders")] on its struct, then one #[with_step(Charge, name = "charge")] line per step, in order 5, 6
A workflow instance and its initial data #[derive(InitialData)] on a struct, then Orders::builder().initial_data(order).create()? 5, 24
An executor, and running an instance let mut executor = local_executor_for!(Orders);, then executor.run(instance) for each instance, which returns Result<JourneyResult, Refusal> 5, 24
Reading the result and its output a match on result.status: JourneyStatus::Succeeded, Failed { failure, .. } with failure.cause(), or Aborted(abort) with abort.reason(); and #[derive(Output)] on a struct read with result.output::<Order>()? 5, 6, 25
A contributor a parameter of run marked #[contributor], of type Contributor<'_>, then contributor.contribute("key", value) 6
A service and its provider a parameter of run marked #[service], of type &dyn Trait; a method of the workflow's #[workflow] impl block marked #[provider], or #[provider(key = "...", per_attempt)] for a new instance for each attempt, returning Result<Provided<dyn Trait>, Error>, made with provide!(...); a per-attempt provider may request #[attempt] 7, 13
A reporter impl Reporter for Log, listed with reporters = [Log, Desk] on #[workflow(...)] 8, 10
A step's own events a parameter of run marked #[reporter], of type StepReporter<'_>, then reporter.info("...")?, .warning(...) or .error(...) 9
A journey ID generator a method of the same block marked #[id_generator], returning Result<String, Error> 11
A retry budget retry_budget = 1 on the step's #[with_step] line 12
An abnormal termination run returns Err(error), often through ?; no_retry_on_abnormal_termination on the step's #[with_step] line keeps it from spending the retry budget 12
A rescue step #[derive(RescueStep)] on its struct, and #[rescue_step] on the block holding fn run(self, ...) -> Result<RescueOutcome, Error>, which may request #[reason]; attached with rescue = RenewCard on the step's #[with_step] line 14
A step policy and its hooks #[step_policy(name = "audit")] on its block, and a method marked with its hook, such as #[on_step_success]; attached with policies = [Audit] on a #[with_step] line 15
Giving a step up early a method marked #[on_step_retry] or #[on_step_abnormal_termination], returning Result<Option<FailWorkflow>, Error>, with Self::fail_workflow("code") or Self::carry_on() 17
What a hook requests parameters marked #[from_step], #[from_workflow], #[step_name], #[reason], #[role] or #[contributor] 15, 17, 18, 19
A workflow policy and its hooks #[workflow_policy(name = "notify")] on its block, and a method marked #[on_workflow_success] or #[on_workflow_failure]; attached with policies = [Notify] on #[workflow(...)] 18
A role a trait, and #[role] on the workflow's implementation of it; a hook requests it as #[role] messages: &dyn Messages 19
An input adapter a method of the workflow's #[workflow] impl block, marked #[input_adapter(steps = ["ship"])], returning Result<Option<AnyValue>, Error>, made with Self::supply(value) or Self::from_data_bag() 21
A value of your own type #[derive(Clone, Serialize, Deserialize)] on its struct, with the serde crate and its derive feature 21
Finishing a journey early Self::finish_workflow(), returned by a method marked #[on_step_success] 22
Undoing a step's work when it is given up a method marked #[on_step_failure], returning Result<Option<FailWorkflow>, Error>, which may ask for #[cause] cause: StepFailureCause; and a method of the policy's own, without a mark, that its hooks call 23
The asynchronous execution mode the async feature; #[async_trait], from itinera::mode, on the trait of each service that waits, and each implementation; async fn run and async fn hooks; a role's trait that is Sync; local_executor_for!(Orders).run(instance).await, with an executor for each journey running at the same time 26
A step tested alone with the testing feature under [dev-dependencies], and only inside #[cfg(test)] mod tests, a #[test] function calling Charge { ... }.run(&fake, contributions.contributor()), with Contributions from itinera::journey and StepEventReporter from itinera::step; for an asynchronous step, an async fn marked #[tokio::test] that awaits run, with events.async_reporter() 27
A hook or an input adapter tested alone FailedShipping.before_retrying(Some(Reason::from("code")), receipt, amount, &refunds, contributions.contributor())?, read with keeps_default() or fails_workflow() from itinera::policy::ReturnedLifecycle, or Orders { ... }.parcels("weight", parcel)? 28
A scripted run with the testing feature under [dev-dependencies], and only inside #[cfg(test)] mod tests, instance.scripted().step("charge").will_fail("code").on_attempt(2).will_succeed().and_step("charge_rescue").will_succeed().run()?, which returns a ScriptedRun 29
A fake provider and a journey's path with the testing feature under [dev-dependencies], and only inside #[cfg(test)] mod tests, .fake_provider::<dyn Payments>("bank", fake) on the builder, where fake returns Ok(provide!(...)), and .reporter(recorder.clone()) with a RecordingReporter, then recorder.path() 30
A reporter that fails report returning Err, which aborts the journey; the result's Abort::ReporterFailed(error) holds the error 31
A reporter that prints every event DebugReporter, from itinera::report, in reporters = [DebugReporter, ...] 32
Global metadata .reporters_global_metadata("customer", value) on the instance builder, or reporter.set_global_metadata("receipt", value)? in a step with #[reporter] mut reporter: StepReporter<'_>, received by Reporter::set_global_metadata(&mut self, key, value) 33
What only a hook can know parameters marked #[journey_id] journey: &JourneyId, #[attempt] attempt: NonZeroU32 and #[error] error: &Error on on step abnormal termination, or Option<&Error> on on step retry and on step failure 34
A key of its own, and a provider for some steps #[input("card")] expired: String or #[service("cards")] registry: &dyn Cards; #[provider(steps = ["charge_rescue"])], returning Provided::from_box(boxed).with_data(value) 35
An order stopped before its journey create() returning Err when the ID generator fails; run returning Err(refusal) when a reporter's set_global_metadata returns Err 36
The listing, and the violations of admission Orders::descriptor().listing(), with Workflow from itinera::workflow in scope, giving a ListedStep for each step; with the attributes, a violation is a compile error 37
A workflow declared by hand WorkflowDescriptor::builder("orders").step(StepDescriptor::new(step_name!("price"), Pricing)).build(), which returns Result<WorkflowDescriptor<Orders>, Violations>; a StepFactory and a Step for a step, a hook's trait such as OnStepSuccess<Orders> for a policy 38

For the asynchronous form, as chapter 26 shows, turn on the async feature, mark the trait of each service that waits, and its implementations, #[async_trait], write async fn run, which makes the workflow asynchronous, and async fn hooks, keep a synchronous reporter under reporters = [...], or declare an AsyncReporter under async_reporters = [...], as chapter 31 shows, and await the run of the executor local_executor_for! makes, an AsyncLocalExecutor.