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("{0}")]
30    Help(String),
31
32    #[error("Invalid usage config")]
33    #[diagnostic(transparent)]
34    Miette(#[from] miette::MietteError),
35
36    #[error(transparent)]
37    IO(#[from] std::io::Error),
38
39    #[error(transparent)]
40    Strum(#[from] strum::ParseError),
41
42    #[error(transparent)]
43    FromUtf8Error(#[from] std::string::FromUtf8Error),
44
45    #[cfg(feature = "tera")]
46    #[error(transparent)]
47    TeraError(#[from] tera::Error),
48
49    #[error(transparent)]
50    #[diagnostic(transparent)]
51    KdlError(#[from] kdl::KdlError),
52
53    #[error(transparent)]
54    #[diagnostic(transparent)]
55    XXError(#[from] xx::error::XXError),
56
57    #[error("Variadic argument <{name}> requires at least {min} value(s), got {got}")]
58    VarArgTooFew {
59        name: String,
60        min: usize,
61        got: usize,
62    },
63
64    #[error("Variadic argument <{name}> accepts at most {max} value(s), got {got}")]
65    VarArgTooMany {
66        name: String,
67        max: usize,
68        got: usize,
69    },
70
71    #[error("Variadic flag --{name} requires at least {min} value(s), got {got}")]
72    VarFlagTooFew {
73        name: String,
74        min: usize,
75        got: usize,
76    },
77
78    #[error("Variadic flag --{name} accepts at most {max} value(s), got {got}")]
79    VarFlagTooMany {
80        name: String,
81        max: usize,
82        got: usize,
83    },
84
85    #[error("Invalid file path: {0}")]
86    InvalidPath(String),
87
88    #[error("Unsupported shell: {0}")]
89    UnsupportedShell(String),
90}
91pub type Result<T> = std::result::Result<T, UsageErr>;
92
93#[macro_export]
94macro_rules! bail_parse {
95    ($ctx:expr, $span:expr, $fmt:literal) => {{
96        let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
97        let msg = format!($fmt);
98        let err = $ctx.build_err(msg, span);
99        return std::result::Result::Err(err);
100    }};
101    ($ctx:expr, $span:expr, $fmt:literal, $($arg:tt)*) => {{
102        let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
103        let msg = format!($fmt, $($arg)*);
104        let err = $ctx.build_err(msg, span);
105        return std::result::Result::Err(err);
106    }};
107}