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}