Skip to main content

clap_tui/
error.rs

1use thiserror::Error;
2
3/// Errors returned by `clap-tui`.
4#[derive(Debug, Error)]
5#[non_exhaustive]
6pub enum TuiError {
7    /// Terminal IO error.
8    #[error("terminal error: {0}")]
9    Terminal(#[from] std::io::Error),
10    /// Clap validation error.
11    #[error("clap error: {0}")]
12    Clap(#[from] clap::Error),
13    /// Application callback error.
14    #[error("runner error: {0}")]
15    Runner(Box<dyn std::error::Error + Send + Sync>),
16    /// Lower-level TUI flow exited without running.
17    ///
18    /// Higher-level entry points such as `TuiApp::run`, `Tui::run`, and `run_with_matches`
19    /// normalize this into `Ok(None)` or let callers decide what cancellation means.
20    #[error("cancelled")]
21    Cancelled,
22    /// Requested entrypoint subcommand does not exist on the top-level render command.
23    #[error("{}", unknown_entrypoint_message(name, candidates))]
24    UnknownEntrypoint {
25        /// Requested canonical top-level subcommand name.
26        name: String,
27        /// Available canonical top-level subcommand names in declaration order.
28        candidates: Vec<String>,
29    },
30}
31
32fn unknown_entrypoint_message(name: &str, candidates: &[String]) -> String {
33    if candidates.is_empty() {
34        format!("unknown TUI entrypoint `{name}`; no top-level subcommands are available")
35    } else {
36        format!(
37            "unknown TUI entrypoint `{name}`; expected one of: {}",
38            candidates.join(", ")
39        )
40    }
41}