Start

Examples

Each example adds exactly one idea to the one before it. All of them run offline, have their own tests, and live in rustclamp/examples.

00 · Pico Works

The smallest Clamp application: plain Rust plus one entrypoint. It proves the facade costs nothing when you use nothing else — no allocations, no registries, no threads, zero bytes of binary size over plain Rust in the Phase 1 measurement.

use rustclamp::prelude::*;

fn main() {
    Clamp::run(|| {
        println!("Hello Clamp");
    });
}

The entrypoint really is this small:

pub struct Clamp;

impl Clamp {
    #[inline]
    pub fn run<F, R>(run: F) -> R
    where
        F: FnOnce() -> R,
    {
        run()
    }
}

01 · Capability Prototype

Business code depends on the Clock capability from Core, not on a concrete clock. You pass the implementation in yourself. No Kernel, no facade.

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

struct SystemClock;

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

fn main() {
    println!("{}", Greeter::new(SystemClock).greet("world"));
}

02 · Module Prototype

A GreeterModule declares that it requires a Clock; a FixedClockModule declares that it provides one. Kernel resolves the requirement by type. Missing, ambiguous and cyclic compositions return structured errors. See Modules.

let clock = FixedClockModule(UNIX_EPOCH + std::time::Duration::from_secs(42));
let provisions = [Provision::<ClockCapability>::from_module(&clock)];
let requirement = CapabilityRequirement::<ClockCapability>::from_module::<GreeterModule>();
let clock = Resolver::resolve::<ClockCapability>(
    requirement.required_by(),
    &provisions,
    requirement.selected_provider(),
)?;
let greeter = Greeter::new(clock);

03 · Contribution Prototype

Modules contribute CLI commands to a typed command target. Core and Kernel only know “a declaration for a target”; the CLI target owns the command rules — unique names, alphabetical order, what an empty tree means. See Contributions.

let target = CliCommandTarget::<PublicCommands>::new();
let commands = TargetComposition::<_, PublicCommands>::new(vec![
    (HelloModule::ID, HelloModule::contribution()),
    (GoodbyeModule::ID, GoodbyeModule::contribution()),
])
.build(Some(&target))
.expect("the CLI target accepts these declarations")
.expect("a target produces a command tree");

println!("hello: {}", commands.execute("hello", Some(&clock)).unwrap());

04 · Process Prototype

One application blueprint resolves a CLI process and a Worker process independently. Each gets only the modules it can reach; Worker-only configuration is read only by Worker. The frozen plan can be printed. See Processes.

cargo run --offline --locked --manifest-path examples/04-process/Cargo.toml --example 04-process -- inspect cli

One recorded inspection run showed the Clock path as:

example.process.cli-root -> example.process.greeting-command -> example.process.clock

05 · Lifecycle In progress

A synchronous lifecycle coordinator tested against fake resources: providers initialize first, consumers stop first, readiness is separate from “started”, and shutdown drains before it cancels. It is in development and not yet on the main branch. See Lifecycle.