Concepts

Capabilities Prototype

A capability is an ability the running application offers — telling the time today; a database or a cache later. Code asks for the ability. It never asks for a particular client.

The first capability: Clock

Core defines the Clock trait and a typed ClockCapability marker. Anything that can tell the time can provide it.

use std::time::SystemTime;
use rustclamp_core::Clock;

struct SystemClock;

impl Clock for SystemClock {
    fn now(&self) -> SystemTime {
        SystemTime::now()
    }
}

A test swaps in a fixed clock without touching the code that reads it. That is the whole value of the capability: the dependency points at the ability, so the implementation is replaceable.

Two ways to supply one

Direct injection

Without Kernel you pass the value in yourself: Greeter::new(SystemClock). Example 01 does exactly this and nothing more.

Resolved by Kernel

When modules declare Requires<ClockCapability> and Provides<ClockCapability>, Kernel finds the provider by type. See Modules for the resolution rules.

What a capability is not

  • Not arbitrary state. Request id, principal, transaction and tick are ordinary call data passed to the operation, not capabilities (Phase 2 evidence).
  • Not a service locator. There is no ctx.get::<T>() and no giant context object. Requirements are declared, typed and visible.
  • Not a contribution. A capability is used by code while it runs. A contribution is consumed while a subsystem is being built.

Qualifiers

One application can hold more than one provider of the same capability for different purposes. The process prototype keeps them apart with qualifiers, and inspection output lists the resolved capability together with its qualifier.

Planned capabilities

The design names more capabilities — async runtime, database, cache — always as abstractions rather than products (AsyncRuntime, not Tokio). None of them exist yet. Planned