usage/
error.rs

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}