Files
boxmaker/crates/toolkit/src/lib.rs
T
kyleandClaude Opus 5.5 2b3ae080b4 proto becomes bxcore, the one shared crate (M5b task 00)
Done the way the owner asked and the spike mapped: the crate and the
manifests renamed, then what the build reported fixed. Layers: 138
"proto unresolved" errors across 169 files; cargo fmt reordering
imports; six fixture paths built as strings in brokerd's and bxctl's
tests, which the compiler cannot see, and comments naming
crates/proto/; the crate-dependency check and its self-test. One more
the spike did not reach: a `\nproto =` key inside a printf format in
the self-test, which a word-boundary replacement skips because `n` and
`p` are both word characters.

make gate: gate: ok, 944 tests; no new entry in /tmp.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 01:48:38 -07:00

101 lines
2.4 KiB
Rust

//! The programs that run inside tool containers.
use bxcore::tools::{HttpFetchArgs, ReadFileArgs, ShellArgs, WriteFileArgs};
pub mod addr;
pub mod egress;
pub mod fetch;
pub mod files;
pub mod input;
pub mod shell;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Exit {
Done,
ToolError,
Misuse,
}
impl Exit {
/// 0, 1, 2. No `as` cast: a `match`.
pub fn code(self) -> u8 {
match self {
Exit::Done => 0,
Exit::ToolError => 1,
Exit::Misuse => 2,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Outcome {
pub exit: Exit,
pub stdout: String,
pub stderr: String,
}
impl Outcome {
pub fn done(stdout: String) -> Outcome {
Outcome {
exit: Exit::Done,
stdout,
stderr: String::new(),
}
}
pub fn tool_error(stdout: String) -> Outcome {
Outcome {
exit: Exit::ToolError,
stdout,
stderr: String::new(),
}
}
pub fn misuse(stderr: String) -> Outcome {
Outcome {
exit: Exit::Misuse,
stdout: String::new(),
stderr,
}
}
}
/// Run tool `name` with the arguments on `stdin`.
pub fn run(name: &str, stdin: &mut dyn std::io::Read) -> Outcome {
let text = match input::read_input(stdin) {
Ok(t) => t,
Err(e) => return Outcome::misuse(format!("toolkit: {e}")),
};
match name {
"read_file" => {
let args = match input::parse::<ReadFileArgs>(name, &text) {
Ok(a) => a,
Err(e) => return Outcome::misuse(e),
};
files::read_file(&args)
}
"write_file" => {
let args = match input::parse::<WriteFileArgs>(name, &text) {
Ok(a) => a,
Err(e) => return Outcome::misuse(e),
};
files::write_file(&args)
}
"shell" => {
let args = match input::parse::<ShellArgs>(name, &text) {
Ok(a) => a,
Err(e) => return Outcome::misuse(e),
};
shell::shell(&args)
}
"http_fetch" => {
let args = match input::parse::<HttpFetchArgs>(name, &text) {
Ok(a) => a,
Err(e) => return Outcome::misuse(e),
};
fetch::fetch(&args)
}
_ => Outcome::misuse(format!("toolkit: unknown tool {name:?}")),
}
}