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}
50pub type Result<T> = std::result::Result<T, UsageErr>;
51
52#[macro_export]
53macro_rules! bail_parse {
54 ($ctx:expr, $span:expr, $fmt:literal) => {{
55 let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
56 let msg = format!($fmt);
57 let err = $ctx.build_err(msg, span);
58 return std::result::Result::Err(err);
59 }};
60 ($ctx:expr, $span:expr, $fmt:literal, $($arg:tt)*) => {{
61 let span: miette::SourceSpan = ($span.offset(), $span.len()).into();
62 let msg = format!($fmt, $($arg)*);
63 let err = $ctx.build_err(msg, span);
64 return std::result::Result::Err(err);
65 }};
66}