Skip to main content

mudders/
error.rs

1use std::error::Error;
2use std::fmt::{self, Display, Formatter};
3use std::num::TryFromIntError;
4
5/// Checks for a condition, and if it false, returns the given error.
6///
7/// Intended usage:
8///
9/// ```
10/// fn fallibe_function(i: i32) -> Result<(), String> {
11///     ensure! { i > 5, "i may not be less than 5" }
12///     Ok(())
13/// }
14/// ```
15///
16/// Note: Uses From::from on $error.
17macro_rules! ensure {
18    ($predicate:expr, $error:expr) => {
19        if !$predicate {
20            return Err(From::from($error));
21        }
22    };
23}
24
25/// Error that might occur when generating new strings.
26#[derive(Debug, Clone, PartialEq)]
27pub enum GenerationError {
28    NonAsciiInput(NonAsciiError),
29    UnknownCharacters(String),
30    MatchingStrings(String),
31    Internal(InternalError),
32}
33
34impl From<NonAsciiError> for GenerationError {
35    fn from(s: NonAsciiError) -> GenerationError {
36        GenerationError::NonAsciiInput(s)
37    }
38}
39impl From<InternalError> for GenerationError {
40    fn from(s: InternalError) -> GenerationError {
41        GenerationError::Internal(s)
42    }
43}
44
45impl Display for GenerationError {
46    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
47        match self {
48            GenerationError::NonAsciiInput(err) => err.fmt(f),
49            GenerationError::UnknownCharacters(string) => write!(
50                f,
51                "the given string contained characters not in the SymbolTable: {}",
52                string
53            ),
54            GenerationError::MatchingStrings(s) => write!(f, "the given strings are equal: {}", s),
55            GenerationError::Internal(err) => write!(
56                f,
57                "Internal error: {}; this is a bug in mudders, please report it!",
58                err
59            ),
60        }
61    }
62}
63
64impl Error for GenerationError {}
65
66/// Errors that are likely not user errors, but bugs in the library.
67#[derive(Debug, Clone, Copy, PartialEq)]
68pub enum InternalError {
69    FailedToGetMiddle,
70    NotEnoughItemsInPool,
71    WrongCharOrder(char, char),
72}
73
74impl Display for InternalError {
75    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
76        match self {
77            InternalError::FailedToGetMiddle => write!(f, "failed to get middle element from pool"),
78            InternalError::NotEnoughItemsInPool => {
79                write!(f, "failed to get the requested amount of items")
80            }
81            InternalError::WrongCharOrder(start, end) => write!(
82                f,
83                "expected first char ({first:?}) to precede second ({second:?}), but it didn't",
84                first = start,
85                second = end
86            ),
87        }
88    }
89}
90
91impl Error for InternalError {}
92
93/// An error indicating that a character passed to mudders is not in ASCII range.
94#[derive(Debug, Clone, Copy, PartialEq)]
95pub enum NonAsciiError {
96    InvalidU8(TryFromIntError),
97    NonAsciiU8,
98}
99
100impl From<TryFromIntError> for NonAsciiError {
101    fn from(s: TryFromIntError) -> NonAsciiError {
102        NonAsciiError::InvalidU8(s)
103    }
104}
105
106impl Display for NonAsciiError {
107    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
108        match self {
109            NonAsciiError::InvalidU8(error) => error.fmt(f),
110            NonAsciiError::NonAsciiU8 => write!(f, "a given byte was not within ASCII range"),
111        }
112    }
113}
114
115impl Error for NonAsciiError {}
116
117/// Errors that might occur on SymbolTable construction.
118#[derive(Debug, Clone, Copy, PartialEq)]
119pub enum CreationError {
120    NonAscii(NonAsciiError),
121    EmptySlice,
122}
123
124impl From<NonAsciiError> for CreationError {
125    fn from(s: NonAsciiError) -> CreationError {
126        CreationError::NonAscii(s)
127    }
128}
129
130impl Display for CreationError {
131    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
132        match self {
133            CreationError::NonAscii(err) => err.fmt(f),
134            CreationError::EmptySlice => write!(f, "tried to create an empty SymbolTable"),
135        }
136    }
137}