Files
wds/src/cli.rs
T
2026-06-13 13:44:02 +02:00

45 lines
1.5 KiB
Rust

//! Konsolen-REPL — Headless-Treiber für Tests und Betrieb ohne GPU.
//!
//! Liest Zeilen von stdin, gibt sie an `Session::exec` und druckt die
//! Ausgabe. Befehls- und Dialoglogik liegen in `session`, damit das
//! Fenster-Frontend dieselbe Session ohne Duplikat steuern kann.
use std::io::{self, Write};
use crate::session::{Mode, Session};
pub fn run(mut session: Session, signals_path: &str) {
println!("wds-Konsole — {} Signale aus {}. `help` für Befehle.",
session.game.signals.len(), signals_path);
// Reserviertes `[init]`-Signal: KV-Defaults setzen, bevor Stories laufen.
for line in session.start() { println!("{line}"); }
loop {
let Some(input) = read_line(prompt_for(&session.mode)) else { break };
let r = session.exec(input.trim());
for line in r.output { println!("{line}"); }
if r.quit { break; }
}
}
/// Prompt je nach Zustand: Befehl, Dialog-Weiterblättern oder Choice-Wahl.
fn prompt_for(mode: &Mode) -> &'static str {
match mode {
Mode::Dialog(d) if !d.choices.is_empty() => " wahl> ",
Mode::Dialog(_) => " [Enter] ",
Mode::Free => "> ",
}
}
/// Zeile von stdin lesen; `None` bei EOF (Ctrl-D) oder Lesefehler.
fn read_line(prompt: &str) -> Option<String> {
print!("{prompt}");
io::stdout().flush().ok();
let mut buf = String::new();
match io::stdin().read_line(&mut buf) {
Ok(0) | Err(_) => None,
Ok(_) => Some(buf.trim_end().to_string()),
}
}