Skip to main content

Crate ctl_core

Crate ctl_core 

Source
Expand description

Shared clap chassis and presentation kernel for the *ctl CLIs. A library, not a command.

A consumer owns typed domain requests and results. ctl-core owns parsing, help, Usage mounts, color policy, terminal layout, streams, errors, and JSON emission. One serializable result feeds pretty, colorless, and JSON output.

§Quick start

use ctl_core::prelude::*;
use serde::Serialize;

#[derive(Parser)]
#[command(version, about = "example")]
struct Cli {
    #[command(flatten)]
    output: OutputArgs,
    #[command(subcommand)]
    command: Command,
}

#[derive(Subcommand)]
enum Command {
    /// Show status.
    Status,
}

#[derive(Serialize)]
struct Status {
    pending: usize,
}

impl Present for Status {
    fn present(&self) -> Document {
        Document::new().fields(Fields::new().row("pending", self.pending.to_string()))
    }
}

fn main() -> ExitCode {
    App::<Cli>::new("example")
        .view(|cli| cli.output.view())
        .run(|cli| match cli.command {
            Command::Status => Ok(Status { pending: 0 }),
        })
}

The default app feature covers this example.

§How output flows

Clap types ──→ App ──→ typed domain result ──┬──→ JSON
                                             └──→ Document ──→ pretty/colorless
  • Domain handlers return data. They do not print, read terminal state, or choose the output format.
  • Present maps a serializable result to a semantic Document.
  • View serializes the result for JSON and renders its document for pretty and colorless output.
  • JSON always goes to stdout and never contains ANSI. Human failures go to stderr.
  • The terminal engines, Comfy Table, Anstyle, and Anstream, stay private.

prelude is the one import a *ctl binary needs.

§Cargo features

Features are additive. Unused ones do not compile clap, comfy-table, or schemars.

  • app (enabled by default) — Complete typed CLI lifecycle over the shared help and view layers.
  • cli (enabled by default) — Clap derive helpers (OutputArgs, DryRunArgs) and parser defaults.
  • document (enabled by default) — Semantic presentation documents without a terminal engine.
  • json (enabled by default) — Serde models and the JSON view.
  • render (enabled by default) — Terminal rendering for semantic documents. Engine crates stay private.
  • schema — JSON Schema for the envelope and enums (schemars).
  • help (enabled by default) — Styled -h/--help through the shared document renderer.
  • view (enabled by default) — Pretty / JSON / colorless emitters over serializable models.
  • surface-model — Clap-derived operator metadata without serialization or a template engine.
  • surface-serde — Serializable Surface metadata without a template engine.
  • surface-templates — Shared MiniJinja fragments for committed operator documents.
  • surface — Compatibility aggregate for the complete operator-document surface.
  • served — Files a repository serves, rendered from templates that declare their own target (served::render, Served::write).
  • validate — Garde rules every declared schema shares (validate).
  • input — Declared input: read, parse with serde-saphyr, validate once with garde, and place every problem on its file and line through yamled.
  • input-toml — Declared input from TOML: Input::open reads .toml files, and the toml crate’s span-carrying tree places each problem on its line and column. Enables input, whose Limits it shares.
  • fixture — Temporary file trees for integration tests: Suite, its scenarios, and one call per file.
  • usage — Mise Usage spec from clap (--usage-spec, served-task mount).

Re-exports§

pub use document::Document;document
pub use flags::EnvPrefix;cli
pub use view::Present;view

Modules§

appapp
Fluent typed CLI lifecycle.
color
Color policy (auto / always / never).
documentdocument
Semantic presentation document shared by every ctl CLI.
fixturefixture
Files for integration tests, written through one call instead of fs::create_dir_all, fs::write, and an expect per file.
flagscli
Shared clap flatten structs.
format
Output representation (pretty / json).
helphelp
Styled help extracted from Clap and rendered as a semantic document.
inputinput
Declared input: read a file, parse its shape with serde-saphyr (YAML) or the toml crate (TOML, with input-toml), validate it once with garde, and report every problem on its file and line.
model
Schema-first wire types. Views render these; they do not own data.
parsercli
Parser defaults. -h / --help and -V / --version stay on.
prelude
Import once in a *ctl main.rs.
renderrender
Render semantic documents without exposing the terminal engine.
servedserved
Files a repository serves, rendered from templates that declare where they go.
surfacesurface-model
Clap-derived operator metadata and validation.
tablerender
Compatibility helpers over the semantic document renderer.
usageusage
Mise Usage spec from a clap Command.
validatevalidate
Garde rules every declared schema shares, so a repository’s config and a template’s own exports are held to the same rules and complain the same way.
viewview
Pretty, colorless, and JSON emission from one typed model.