mt940/
errors.rs

1use thiserror::Error;
2
3use crate::Rule;
4
5#[derive(Debug, Clone, Eq, PartialEq, Error)]
6pub enum DateParseError {
7    #[error("Date parsing failed for date: '{}-{}-{}'", year, month, day)]
8    OutOfRange {
9        year: String,
10        month: String,
11        day: String,
12    },
13
14    #[error("Pest parsing error: {}", _0)]
15    PestParseError(pest::error::Error<Rule>),
16}
17
18impl From<pest::error::Error<Rule>> for DateParseError {
19    fn from(err: pest::error::Error<Rule>) -> DateParseError {
20        DateParseError::PestParseError(err)
21    }
22}
23
24/// Error thrown if a variant for an enum can't be found.
25#[derive(Debug, Clone, Eq, PartialEq, Error)]
26#[error("Variant not found: {}", _0)]
27pub struct VariantNotFound(pub String);
28
29/// Error thrown when parsing of a MT940 amount fails.
30#[derive(Debug, Clone, Eq, PartialEq, Error)]
31pub enum AmountParseError {
32    #[error("Too many commas in amount: '{}'", _0)]
33    TooManyCommas(String),
34
35    #[error("No comma found in amount: '{}'", _0)]
36    NoComma(String),
37
38    #[error("Couldn't parse as integer: '{}'", _0)]
39    IntParseError(std::num::ParseIntError),
40}
41
42/// Error thrown when parsing fails.
43#[derive(Debug, Clone, Eq, PartialEq, Error)]
44pub enum ParseError {
45    #[error("Pest parsing error: {}", _0)]
46    PestParseError(pest::error::Error<Rule>),
47
48    #[error("{}", _0)]
49    UnexpectedTagError(UnexpectedTagError),
50
51    #[error("{}", _0)]
52    DateParseError(DateParseError),
53
54    #[error("{}", _0)]
55    RequiredTagNotFoundError(RequiredTagNotFoundError),
56
57    #[error("Unknown tag: '{}'", _0)]
58    UnknownTagError(String),
59
60    #[error("{}", _0)]
61    VariantNotFound(VariantNotFound),
62
63    #[error("{}", _0)]
64    AmountParseError(AmountParseError),
65}
66
67impl From<pest::error::Error<Rule>> for ParseError {
68    fn from(err: pest::error::Error<Rule>) -> ParseError {
69        ParseError::PestParseError(err)
70    }
71}
72
73impl From<DateParseError> for ParseError {
74    fn from(err: DateParseError) -> ParseError {
75        ParseError::DateParseError(err)
76    }
77}
78
79impl From<UnexpectedTagError> for ParseError {
80    fn from(err: UnexpectedTagError) -> ParseError {
81        ParseError::UnexpectedTagError(err)
82    }
83}
84
85impl From<RequiredTagNotFoundError> for ParseError {
86    fn from(err: RequiredTagNotFoundError) -> ParseError {
87        ParseError::RequiredTagNotFoundError(err)
88    }
89}
90
91impl From<VariantNotFound> for ParseError {
92    fn from(err: VariantNotFound) -> ParseError {
93        ParseError::VariantNotFound(err)
94    }
95}
96
97impl From<AmountParseError> for ParseError {
98    fn from(err: AmountParseError) -> ParseError {
99        ParseError::AmountParseError(err)
100    }
101}
102
103/// Error thrown when an unexpected tag was found.
104///
105/// Some tags must never follow other tags. If that happens for some reason, we can safely assume
106/// that the input data is faulty.
107#[derive(Debug, Clone, Eq, PartialEq, Error)]
108#[error(
109    "Unexpected tag '{}' found. Expected one of '{:?}'. The tag before this one was '{}'.",
110    current_tag,
111    expected_tags,
112    last_tag
113)]
114pub struct UnexpectedTagError {
115    current_tag: String,
116    last_tag: String,
117    expected_tags: Vec<String>,
118}
119
120impl UnexpectedTagError {
121    pub fn new(
122        current_tag: &str,
123        last_tag: &str,
124        expected_tags: Vec<String>,
125    ) -> UnexpectedTagError {
126        UnexpectedTagError {
127            current_tag: current_tag.to_string(),
128            last_tag: last_tag.to_string(),
129            expected_tags,
130        }
131    }
132}
133
134/// Error thrown if a required tag was not found.
135#[derive(Debug, Clone, Eq, PartialEq, Error)]
136#[error("Required tag '{}' not found.", required_tag)]
137pub struct RequiredTagNotFoundError {
138    required_tag: String,
139}
140
141impl RequiredTagNotFoundError {
142    pub fn new(tag: &str) -> RequiredTagNotFoundError {
143        RequiredTagNotFoundError {
144            required_tag: tag.to_string(),
145        }
146    }
147}