observer-rust 0.1.1

Rust-facing runtime and registration types for the Observer platform
Documentation
<!-- SPDX-FileCopyrightText: 2026 Alexander R. Croft -->
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->

# observer-rust

`observer-rust` is the low-level Rust runtime surface for defining Observer-compatible test registries.

It is intentionally small. This crate does not provide macros or a human-first authoring DSL. Instead, it exposes the deterministic registration and execution types that higher-level Rust integrations build on.

## What It Provides

- `TestContext` for collecting stdout, stderr, exit code, and telemetry
- `TestOutcome` and telemetry value types
- `TestRegistration` for explicit test registration
- `Registry` for publishing a static test set to Observer
- `sorted_validated_tests` for deterministic ordering and duplicate checks

## When To Use It

Use `observer-rust` if you are:

- building your own Rust-facing test authoring layer
- generating Rust registrations mechanically
- integrating Rust tests into a custom provider host

If you want a ready-made provider host CLI, pair this crate with `observer-rust-host`.

If you want a higher-level authoring library with macros and starter projects, use `observer-rust-lib`.

## Minimal Example

```rust
use observer_rust::{Registry, TestContext, TestRegistration};

fn smoke(ctx: &mut TestContext) {
    ctx.write_out(b"ok\n");
    assert!(ctx.emit_metric("wall_time_ns", 42.0));
}

struct ExampleRegistry;

impl Registry for ExampleRegistry {
    fn tests() -> &'static [TestRegistration] {
        static TESTS: [TestRegistration; 1] = [TestRegistration {
            canonical_name: "Pkg::Smoke",
            target: "pkg::smoke",
            function: smoke,
            file: file!(),
            line: line!(),
            module_path: module_path!(),
        }];
        &TESTS
    }
}
```

Before a registry is exposed to Observer, call `sorted_validated_tests::<YourRegistry>()` to enforce the crate's deterministic rules.

## Determinism Rules

- canonical test names must be non-empty
- targets must be non-empty
- canonical names must be unique
- targets must be unique
- final ordering is canonical-name bytes, then target bytes

Those rules are enforced by `sorted_validated_tests` so provider hosts can rely on a stable contract.