Skip to main content

usage/
error.rs

1use miette::{Diagnostic, NamedSource, SourceSpan};
2use thiserror::Error;
3
4#[derive(Error, Diagnostic, Debug)]
5pub enum UsageErr {
6    #[error("Invalid flag `{token}`: {reason}")]
7    InvalidFlag {
8        token: String,
9        reason: String,
10        #[label("{reason}")]
11        span: SourceSpan,
12        #[source_code]
13        input: String,
14    },
15
16    #[error("Missing required flag: --{0} <{0}>")]
17    MissingFlag(String),
18
19    #[error("Invalid usage config")]
20    InvalidInput(
21        String,
22        #[label = "{0}"] SourceSpan,
23        #[source_code] NamedSource<String>,
24    ),
25
26    #[error("Missing required arg: <{0}>")]
27    MissingArg(String),
28
29    #[error("Argument <{0}> can only be set after a `--` separator")]
30    ArgRequiresDoubleDash(String),
31
32    #[error("{0}")]
33    Help(String),
34
35    #[error("Invalid usage config")]
36    #[diagnostic(transparent)]
37    Miette(#[from] miette::MietteError),
38
39    #[error(transparent)]
40    IO(#[from] std::io::Error),
41
42    #[error(transparent)]
43    Strum(#[from] strum::ParseError),
44
45    #[error(transparent)]
46    FromUtf8Error(#[from] std::string::FromUtf8Error),
47
48    #[cfg(feature = "tera")]
49    #[error(transparent)]
50    TeraError(#[from] tera::Error),
51
52    #[error(transparent)]
53    #[diagnostic(transparent)]
54    KdlError(#[from] kdl::KdlError),
55
56    #[error(transparent)]
57    #[diagnostic(transparent)]
58    XXError(#[from] xx::error::XXError),
59
60    #[error("Variadic argument <{name}> requires at least {min} value(s), got {got}")]
61    VarArgTooFew {
62        name: String,
63        min: usize,
64        got: usize,
65    },
66
67    #[error("Variadic argument <{name}> accepts at most {max} value(s), got {got}")]
68    VarArgTooMany {
69        name: String,
70        max: usize,
71        got: usize,
72    },
73
74    #[error("Variadic flag --{name} requires at least {min} value(s), got {got}")]
75    VarFlagTooFew {
76        name: String,
77        min: usize,
78        got: usize,
79    },
80
81    #[error("Variadic flag --{name} accepts at most {max} value(s), got {got}")]
82    VarFlagTooMany {
83        name: String,
84        max: usize,
85        got: usize,
86    },
87
88    #[error("Invalid file path: {0}")]
89    InvalidPath(String),
90
91    #[error("Unsupported shell: {0}")]
92    UnsupportedShell(String),
93}
94pub type Result<T> = std::result::Result<T, UsageErr>;
95
96#[macro_export]
97macro_rules! bail_parse {
98    ($ctx:expr, $span:expr, $fmt:literal) => {{
99        let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
100        let msg = format!($fmt);
101        let err = $ctx.build_err(msg, span);
102        return std::result::Result::Err(err);
103    }};
104    ($ctx:expr, $span:expr, $fmt:literal, $($arg:tt)*) => {{
105        let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
106        let msg = format!($fmt, $($arg)*);
107        let err = $ctx.build_err(msg, span);
108        return std::result::Result::Err(err);
109    }};
110}