blazingly-executor 0.1.1

Runtime-neutral operation executor: extraction, validation, dependency resolution, and typed response projection
Documentation

blazingly-executor

Runtime-neutral operation executor for the Blazingly framework: extraction, validation, dependency resolution, and typed response projection.

This crate makes the operation model of blazingly-core executable. ExecutableOperation pairs an OperationDescriptor with a handler; Plugin scopes group operations with providers (from blazingly-di), lifecycle hooks, and security schemes; ExecutableApp::from_plugin validates and compiles the whole graph once, and invoke runs the full pipeline — hooks, typed extraction, validation (behind the validation feature), the handler, and projection into an ExecutionOutcome — for one operation. The same pipeline serves HTTP requests (routed by blazingly-http) and MCP tool calls. The crate also owns the bounded blocking pool (run_blocking, install_global_blocking_pool) used by synchronous handlers and by blazingly-database.

Standalone use is real: there is no HTTP transport, no macro, and no async runtime here. invoke returns an ordinary future you can drive with any executor, which is how applications are tested in memory. The blazingly facade adds the attribute macros that generate ExecutableOperations from function signatures; without them, the typed, json, and empty constructors build operations by hand, as below.

Direct use

The example depends on blazingly-core and blazingly-json for the descriptor and invocation value types, and uses futures-lite as the executor; any executor works.

use blazingly_core::{HttpMethod, Json, OperationDescriptor, OperationId, ResponseDescriptor};
use blazingly_executor::{ExecutableApp, ExecutableOperation, ExecutionOutcome, Plugin};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let descriptor = OperationDescriptor::new(
        HttpMethod::Get,
        "/health",
        "health.read",
        "Liveness probe",
        None,
        vec![ResponseDescriptor::success(200, None)],
    )?;

    let app = ExecutableApp::from_plugin(
        Plugin::new("app")
            .operation(ExecutableOperation::empty(descriptor, || async { Json("ok") })),
    )?;

    let id = OperationId::new("health.read")?;
    let outcome = futures_lite::future::block_on(app.invoke(&id, blazingly_json::Value::Null));
    assert!(matches!(outcome, ExecutionOutcome::Success { status: 200, .. }));
    Ok(())
}

Links