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(Box<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(Box::new(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(Box<pest::error::Error<Rule>>),
47
48    #[error("{}", _0)]
49    UnexpectedTagError(UnexpectedTagError),
50
51    #[error("{}", _0)]
52    DateParseError(Box<DateParseError>),
53
54    #[error("{}", _0)]
55    RequiredTagNotFoundError(RequiredTagNotFoundError),
56
57    #[error("Unknown tag: '{}'", _0)]
58    UnknownTagError(String),
59
60    #[error("Unknown subfield: '{}'", _0)]
61    UnknownSubfieldError(String),
62
63    #[error("{}", _0)]
64    VariantNotFound(VariantNotFound),
65
66    #[error("{}", _0)]
67    AmountParseError(AmountParseError),
68}
69
70impl From<pest::error::Error<Rule>> for ParseError {
71    fn from(err: pest::error::Error<Rule>) -> ParseError {
72        ParseError::PestParseError(Box::new(err))
73    }
74}
75
76impl From<Box<pest::error::Error<Rule>>> for ParseError {
77    fn from(err: Box<pest::error::Error<Rule>>) -> ParseError {
78        ParseError::PestParseError(err)
79    }
80}
81
82impl From<DateParseError> for ParseError {
83    fn from(err: DateParseError) -> ParseError {
84        ParseError::DateParseError(Box::new(err))
85    }
86}
87
88impl From<UnexpectedTagError> for ParseError {
89    fn from(err: UnexpectedTagError) -> ParseError {
90        ParseError::UnexpectedTagError(err)
91    }
92}
93
94impl From<RequiredTagNotFoundError> for ParseError {
95    fn from(err: RequiredTagNotFoundError) -> ParseError {
96        ParseError::RequiredTagNotFoundError(err)
97    }
98}
99
100impl From<VariantNotFound> for ParseError {
101    fn from(err: VariantNotFound) -> ParseError {
102        ParseError::VariantNotFound(err)
103    }
104}
105
106impl From<AmountParseError> for ParseError {
107    fn from(err: AmountParseError) -> ParseError {
108        ParseError::AmountParseError(err)
109    }
110}
111
112/// Error thrown when an unexpected tag was found.
113///
114/// Some tags must never follow other tags. If that happens for some reason, we can safely assume
115/// that the input data is faulty.
116#[derive(Debug, Clone, Eq, PartialEq, Error)]
117#[error(
118    "Unexpected tag '{}' found. Expected one of '{:?}'. The tag before this one was '{}'.",
119    current_tag,
120    expected_tags,
121    last_tag
122)]
123pub struct UnexpectedTagError {
124    current_tag: String,
125    last_tag: String,
126    expected_tags: Vec<String>,
127}
128
129impl UnexpectedTagError {
130    pub fn new(
131        current_tag: &str,
132        last_tag: &str,
133        expected_tags: Vec<String>,
134    ) -> UnexpectedTagError {
135        UnexpectedTagError {
136            current_tag: current_tag.to_string(),
137            last_tag: last_tag.to_string(),
138            expected_tags,
139        }
140    }
141}
142
143/// Error thrown if a required tag was not found.
144#[derive(Debug, Clone, Eq, PartialEq, Error)]
145#[error("Required tag '{}' not found.", required_tag)]
146pub struct RequiredTagNotFoundError {
147    required_tag: String,
148}
149
150impl RequiredTagNotFoundError {
151    pub fn new(tag: &str) -> RequiredTagNotFoundError {
152        RequiredTagNotFoundError {
153            required_tag: tag.to_string(),
154        }
155    }
156}