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