rusty_vipe/error.rs
1//! Library-level error type for `rusty_vipe`.
2//!
3//! Uses `thiserror` to produce typed errors per AD-009; the binary boundary
4//! wraps these in `anyhow::Result` for human-readable diagnostics.
5
6use std::path::PathBuf;
7
8/// Errors returned by the `rusty_vipe` library API.
9///
10/// Marked `#[non_exhaustive]` so future variant additions are not breaking
11/// changes within a major version.
12///
13/// # Examples
14///
15/// ```
16/// use rusty_vipe::Error;
17///
18/// // Errors implement Display via thiserror.
19/// let e = Error::EditorNonZeroExit(42);
20/// assert_eq!(e.to_string(), "editor exited with code 42");
21/// ```
22#[non_exhaustive]
23#[derive(thiserror::Error, Debug)]
24pub enum Error {
25 /// Opening the controlling terminal failed (`/dev/tty` on Unix or
26 /// `CONIN$`/`CONOUT$` on Windows). Typical cause: process is running
27 /// without a controlling terminal (CI, cron, `nohup`-detached, headless
28 /// Docker `RUN` step).
29 #[error("no controlling terminal; cannot launch editor")]
30 NoControllingTty,
31
32 /// No editor could be resolved from the precedence ladder, OR the
33 /// editor binary was not found at spawn time. Carries the editor
34 /// command or env-var value that was attempted.
35 #[error("editor not found: {0}")]
36 EditorNotFound(String),
37
38 /// The editor exited with a non-zero code. Per FR-006, this carries
39 /// the already-clamped exit code (Unix 1–255 verbatim; Windows 1–254
40 /// verbatim, else clamped to 1). Library consumers can pattern-match
41 /// on a known range.
42 #[error("editor exited with code {0}")]
43 EditorNonZeroExit(i32),
44
45 /// `shell-words` parsing of an editor env value (`$VISUAL`/`$EDITOR`)
46 /// or `--editor=<cmd>` flag failed. Carries the original input.
47 #[error("invalid editor command: {0}")]
48 InvalidEditorCommand(String),
49
50 /// The tempfile no longer exists after the editor returned. Typical
51 /// cause: user deleted it from within the editor (e.g., `:!rm <file>`).
52 #[error("tempfile no longer exists after editor exited: {0}")]
53 TempFileDeleted(PathBuf),
54
55 /// The builder was configured into an impossible state.
56 #[error("invalid builder configuration: {0}")]
57 InvalidBuilderConfiguration(&'static str),
58
59 /// A Default-mode-only setting was passed to Strict mode (or vice versa).
60 #[error("compatibility violation: {0}")]
61 CompatibilityViolation(&'static str),
62
63 #[error("IO error: {0}")]
64 Io(#[from] std::io::Error),
65}