tty_web/
config.rs

1//! CLI configuration parsed from flags and environment variables.
2
3use std::net::IpAddr;
4use std::path::PathBuf;
5
6use clap::{Parser, ValueEnum};
7
8/// Log output format.
9#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
10pub enum LogFormat {
11    /// Human-readable text (default)
12    Text,
13    /// Structured JSON, one object per line
14    Json,
15}
16
17/// Application configuration.
18///
19/// Every field can be set via a CLI flag (`--address`) or an environment
20/// variable (`TTY_WEB_ADDRESS`). Defaults are suitable for local development.
21#[derive(Parser, Debug, Clone)]
22#[command(name = "tty-web", about = "Web-based terminal emulator")]
23pub struct Config {
24    /// Address to bind to
25    #[arg(long, default_value = "127.0.0.1", env = "TTY_WEB_ADDRESS")]
26    pub address: IpAddr,
27
28    /// Port to listen on
29    #[arg(long, default_value_t = 9090, env = "TTY_WEB_PORT")]
30    pub port: u16,
31
32    /// Shell to execute
33    #[arg(long, default_value = "/bin/bash", env = "TTY_WEB_SHELL")]
34    pub shell: String,
35
36    /// Log level (trace, debug, info, warn, error)
37    #[arg(long, default_value = "info", env = "TTY_WEB_LOG_LEVEL")]
38    pub log_level: String,
39
40    /// Log output format
41    #[arg(long, default_value = "text", env = "TTY_WEB_LOG_FORMAT")]
42    pub log_format: LogFormat,
43
44    /// Working directory for new shell sessions
45    #[arg(long, env = "TTY_WEB_PWD")]
46    pub pwd: Option<PathBuf>,
47
48    /// Scrollback buffer size in KiB (default: 256)
49    #[arg(long, default_value_t = 256, env = "TTY_WEB_SCROLLBACK_LIMIT")]
50    pub scrollback_limit: usize,
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_default_values() {
59        let config = Config::parse_from(["tty-web"]);
60        assert_eq!(config.address, "127.0.0.1".parse::<IpAddr>().unwrap());
61        assert_eq!(config.port, 9090);
62        assert_eq!(config.shell, "/bin/bash");
63        assert_eq!(config.log_level, "info");
64        assert_eq!(config.log_format, LogFormat::Text);
65        assert_eq!(config.pwd, None);
66    }
67
68    #[test]
69    fn test_custom_values() {
70        let config = Config::parse_from([
71            "tty-web",
72            "--port",
73            "8080",
74            "--shell",
75            "/bin/sh",
76            "--address",
77            "0.0.0.0",
78            "--log-level",
79            "debug",
80            "--log-format",
81            "json",
82        ]);
83        assert_eq!(config.address, "0.0.0.0".parse::<IpAddr>().unwrap());
84        assert_eq!(config.port, 8080);
85        assert_eq!(config.shell, "/bin/sh");
86        assert_eq!(config.log_level, "debug");
87        assert_eq!(config.log_format, LogFormat::Json);
88    }
89
90    #[test]
91    fn test_pwd_flag() {
92        let config = Config::parse_from(["tty-web", "--pwd", "/tmp"]);
93        assert_eq!(config.pwd, Some(PathBuf::from("/tmp")));
94    }
95}