Files
boxmaker/docs/plans/M4a/files/crates/gatewayd/src/main.rs
T
kyleandClaude Opus 5.5 564875f0a0 M4a tasks 14 and 15: glue written, calls tabled, after task 14's session wrote nothing
Task 14's session read the crate to learn the APIs and planned `connect` in prose until it was
cut off. `connect`, `Gateway::new` and `catch_up` are now written; the task lists every call with
its signature and makes the copy and the failing test the first actions. Task 15's comment is
rewritten one step per item. Both checked to fail, then pass when filled from their comments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 21:50:18 -07:00

45 lines
2.2 KiB
Rust

//! `gatewayd serve --config <path>`: the Mattermost channel. It loads its configuration and its
//! token, prepares its directory, then serves until it must stop (exit 1).
use std::os::unix::fs::DirBuilderExt;
use std::path::Path;
use std::process::ExitCode;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use gatewayd::config::{Config, MATTERMOST_TOKEN};
use gatewayd::secrets;
use gatewayd::serve::{START_FAILED, Tuning, run};
fn main() -> ExitCode {
// `args_os`: the config path need not be UTF-8, and `args` would panic on one that is not.
let args: Vec<std::ffi::OsString> = std::env::args_os().skip(1).collect();
let words: Vec<Option<&str>> = args.iter().map(|a| a.to_str()).collect();
match (words.as_slice(), args.get(2)) {
([Some("serve"), Some("--config"), _], Some(path)) => serve(Path::new(path)),
_ => {
eprintln!("usage: gatewayd serve --config <path>");
ExitCode::from(2)
}
}
}
fn serve(path: &Path) -> ExitCode {
// Each failure prints its message with `eprintln!` and returns `ExitCode::from(1)`.
// 1. `let config = match Config::load(path) { ... }`: an Err(e) prints
// "gatewayd: {e}\n{START_FAILED}".
// 2. `let source = match config.token_source() { ... }`: an Err(why) prints
// "gatewayd: {}: {why}\n{START_FAILED}" with `path.display()`.
// 3. `let loaded = match secrets::load(MATTERMOST_TOKEN, &source, &|k| std::env::var_os(k))`:
// an Err(e) prints "gatewayd: {e}" (the error carries its own pointer).
// Then `if let Some(warning) = &loaded.warning { eprintln!("{warning}"); }`.
// 4. The state file's directory:
// `let dir = config.state_path().parent().map(Path::to_path_buf).unwrap_or_default();`
// `std::fs::DirBuilder::new().recursive(true).mode(0o700).create(&dir)`: an Err(e) prints
// "gatewayd: cannot prepare {}: {e}\n{START_FAILED}" with `dir.display()`.
// 5. `let log: gatewayd::serve::Log = Arc::new(|line: &str| eprintln!("{line}"));`
// `let stop = run(config, loaded.secret, Tuning::default(), log, &AtomicBool::new(false));`
// `eprintln!("{stop}");` and `ExitCode::from(1)`.
todo!()
}