cc_switch_lib/cli/interactive/
mod.rs1use std::io::IsTerminal;
2
3use crate::app_config::AppType;
4use crate::error::AppError;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7enum InteractivePath {
8 Ratatui,
9}
10
11fn decide_interactive_path(
12 legacy_tui_requested: bool,
13 stdin_is_tty: bool,
14 stdout_is_tty: bool,
15) -> Result<InteractivePath, AppError> {
16 if legacy_tui_requested {
17 return Err(AppError::Message(
18 crate::cli::i18n::texts::interactive_legacy_tui_removed().to_string(),
19 ));
20 }
21
22 if !stdin_is_tty || !stdout_is_tty {
23 return Err(AppError::Message(
24 crate::cli::i18n::texts::interactive_requires_tty().to_string(),
25 ));
26 }
27
28 Ok(InteractivePath::Ratatui)
29}
30
31pub fn run(app: Option<AppType>) -> Result<(), AppError> {
32 let path = decide_interactive_path(
33 std::env::var("CC_SWITCH_LEGACY_TUI").ok().as_deref() == Some("1"),
34 std::io::stdin().is_terminal(),
35 std::io::stdout().is_terminal(),
36 )?;
37
38 match path {
39 InteractivePath::Ratatui => crate::cli::tui::run(app),
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::{decide_interactive_path, InteractivePath};
46 use crate::cli::i18n::texts;
47 use crate::error::AppError;
48
49 #[test]
50 fn non_tty_returns_direct_tty_error() {
51 let err = decide_interactive_path(false, true, false)
52 .expect_err("non-tty interactive mode should fail fast");
53
54 match err {
55 AppError::Message(message) => {
56 assert_eq!(message, texts::interactive_requires_tty());
57 }
58 other => panic!("unexpected error variant: {other:?}"),
59 }
60 }
61
62 #[test]
63 fn legacy_env_flag_returns_removed_error() {
64 let err = decide_interactive_path(true, true, true)
65 .expect_err("legacy env flag should no longer enable removed tui");
66
67 match err {
68 AppError::Message(message) => {
69 assert_eq!(message, texts::interactive_legacy_tui_removed());
70 }
71 other => panic!("unexpected error variant: {other:?}"),
72 }
73 }
74
75 #[test]
76 fn tty_without_legacy_flag_uses_new_tui() {
77 let path = decide_interactive_path(false, true, true)
78 .expect("tty interactive mode should enter ratatui");
79
80 assert_eq!(path, InteractivePath::Ratatui);
81 }
82}