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>
45 lines
2.2 KiB
Rust
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!()
|
|
}
|