Skip to main content

with_watch/
error.rs

1use std::{io, path::PathBuf};
2
3use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, WithWatchError>;
6
7#[derive(Debug, Error)]
8pub enum WithWatchError {
9    #[error(
10        "Provide a delegated utility, `--shell <expr>`, or `exec --input <glob>... -- <command> \
11         ...`."
12    )]
13    MissingCommand,
14    #[error("`--shell` cannot be combined with delegated argv or the `exec` subcommand.")]
15    ConflictingModes,
16    #[error("`--shell` requires a non-empty shell expression.")]
17    EmptyShellExpression,
18    #[error("`exec` requires a delegated command after `--`.")]
19    MissingExecCommand,
20    #[error(
21        "No watch inputs could be inferred from the delegated command. Use `with-watch exec \
22         --input <glob>... -- <command> [args...]`."
23    )]
24    NoWatchInputs,
25    #[error("Failed to determine the current working directory: {0}")]
26    CurrentDirectory(#[source] io::Error),
27    #[error("Failed to parse shell expression: {message}")]
28    ShellParse { message: String },
29    #[error("Shell control-flow is out of scope for with-watch v1: {construct}")]
30    UnsupportedShellConstruct { construct: String },
31    #[error("Failed to compile glob pattern `{pattern}`: {message}")]
32    InvalidGlob { pattern: String, message: String },
33    #[error("Could not derive a watch anchor for `{path}`.")]
34    MissingWatchAnchor { path: PathBuf },
35    #[error("Failed to read metadata for `{path}`: {source}")]
36    Metadata {
37        path: PathBuf,
38        #[source]
39        source: io::Error,
40    },
41    #[error("Failed to read `{path}` while hashing: {source}")]
42    HashRead {
43        path: PathBuf,
44        #[source]
45        source: io::Error,
46    },
47    #[error("Failed to create a filesystem watcher: {0}")]
48    WatcherCreate(#[source] notify::Error),
49    #[error("Failed to watch `{path}` recursively: {source}")]
50    WatchPath {
51        path: PathBuf,
52        #[source]
53        source: notify::Error,
54    },
55    #[error("Failed to spawn `{command}`: {source}")]
56    Spawn {
57        command: String,
58        #[source]
59        source: io::Error,
60    },
61    #[error("Failed while waiting for `{command}`: {source}")]
62    Wait {
63        command: String,
64        #[source]
65        source: io::Error,
66    },
67    #[error("Failed to refresh stdout before running the delegated command: {0}")]
68    StdoutRefresh(#[source] io::Error),
69    #[error("`--shell` execution is only supported on Unix-like platforms.")]
70    UnsupportedShellPlatform,
71}
72
73impl WithWatchError {
74    pub fn exit_code(&self) -> i32 {
75        match self {
76            Self::MissingCommand
77            | Self::ConflictingModes
78            | Self::EmptyShellExpression
79            | Self::MissingExecCommand
80            | Self::NoWatchInputs
81            | Self::ShellParse { .. }
82            | Self::UnsupportedShellConstruct { .. }
83            | Self::InvalidGlob { .. }
84            | Self::MissingWatchAnchor { .. }
85            | Self::UnsupportedShellPlatform => 2,
86            Self::CurrentDirectory(_)
87            | Self::Metadata { .. }
88            | Self::HashRead { .. }
89            | Self::WatcherCreate(_)
90            | Self::WatchPath { .. }
91            | Self::Spawn { .. }
92            | Self::Wait { .. }
93            | Self::StdoutRefresh(_) => 1,
94        }
95    }
96}