ragit_cli/
error.rs

1use crate::{ArgCount, ArgType, Span};
2
3pub struct Error {
4    pub span: Span,
5    pub kind: ErrorKind,
6}
7
8pub enum ErrorKind {
9    /// see <https://doc.rust-lang.org/stable/std/num/struct.ParseIntError.html>
10    ParseIntError(std::num::ParseIntError),
11
12    IntegerNotInRange {
13        min: Option<i128>,
14        max: Option<i128>,
15        n: i128,
16    },
17
18    /// (prev_flag, curr_flag)
19    SameFlagMultipleTimes(String, String),
20
21    /// of an arg_flag
22    MissingArgument(String, ArgType),
23
24    WrongArgCount {
25        expected: ArgCount,
26        got: usize,
27    },
28    MissingFlag(String),
29    UnknownFlag {
30        flag: String,
31        similar_flag: Option<String>,
32    },
33}
34
35impl ErrorKind {
36    pub fn render(&self) -> String {
37        match self {
38            ErrorKind::ParseIntError(_) => String::from("Cannot parse int."),
39            ErrorKind::IntegerNotInRange { min, max, n } => match (min, max) {
40                (Some(min), Some(max)) => format!("N is supposed to be between {min} and {max}, but is {n}."),
41                (Some(min), None) => format!("N is supposed to be at least {min}, but is {n}."),
42                (None, Some(max)) => format!("N is supposed to be at most {max}, but is {n}."),
43                (None, None) => unreachable!(),
44            },
45            ErrorKind::SameFlagMultipleTimes(prev, next) => if prev == next {
46                format!("Flag `{next}` cannot be used multiple times.")
47            } else {
48                format!("Flag `{prev}` and `{next}` cannot be used together.")
49            },
50            ErrorKind::MissingArgument(arg, arg_type) => format!(
51                "A {} value is required for flag `{arg}`, but is missing.",
52                format!("{arg_type:?}").to_ascii_lowercase(),
53            ),
54            ErrorKind::WrongArgCount { expected, got } => format!(
55                "Expected {} arguments, got {got} arguments",
56                match expected {
57                    ArgCount::Exact(n) => format!("exactly {n}"),
58                    ArgCount::Geq(n) => format!("at least {n}"),
59                    ArgCount::Leq(n) => format!("at most {n}"),
60                    ArgCount::None => String::from("no"),
61                    ArgCount::Any => unreachable!(),
62                },
63            ),
64            ErrorKind::MissingFlag(flag) => format!("Flag `{flag}` is missing."),
65            ErrorKind::UnknownFlag { flag, similar_flag } => format!(
66                "Unknown flag: `{flag}`.{}",
67                if let Some(flag) = similar_flag {
68                    format!(" There is a similar flag: `{flag}`.")
69                } else {
70                    String::new()
71                },
72            ),
73        }
74    }
75}