#[stepped_task]Expand description
Apply to the SteppedTask trait definition, an
impl SteppedTask<S [, K]> for T block, or — for less boilerplate — an
inherent impl T { ... } block.
Use as #[cano::task::stepped].
Two surface forms on impl blocks:
- Trait-impl form:
#[task::stepped] impl SteppedTask<S> for T { type Cursor = C; async fn step(..) { ... } }— user writes the trait header. The macro async-rewrites theSteppedTaskimpl AND emits a companionimpl Task<S> for Tthat delegatesTask::runvia therun_steppedhelper. - Inherent-impl form:
#[task::stepped(state = S [, key = K])] impl T { async fn step(..) { ... } }— the macro builds theimpl SteppedTask<S [, K]> for Theader from the attribute args, inferstype Cursorfrom theOption<C>third parameter ofstep, enforces thatstepis present (config/namemay be overridden), and emits the same companionimpl Task<S [, K]> for T.
On a trait definition (#[task::stepped] pub trait SteppedTask ...) the macro just performs the
async-fn-in-trait rewrite.
Because a blanket impl<S: SteppedTask<..>> Task<..> for S would conflict (E0119) with the
analogous blanket impls for the other specialized task traits — a type can implement more than
one — the companion Task impl is generated per-use-site rather than as a blanket.
The default config() injected by the inherent form is [TaskConfig::default()]
(exponential backoff with 3 retries).