autoit/error.rs
1//! Error types for AutoIt extraction.
2
3use core::fmt;
4
5/// Crate-wide error type.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Error {
8 kind: ErrorKind,
9}
10
11impl Error {
12 /// Creates a not-recognized error.
13 ///
14 /// # Returns
15 ///
16 /// An [`Error`] wrapping [`RecognitionFailure::NotRecognized`].
17 #[must_use]
18 pub const fn not_recognized() -> Self {
19 Self {
20 kind: ErrorKind::Recognition(RecognitionFailure::NotRecognized),
21 }
22 }
23
24 /// Creates an unsupported-encoding error.
25 ///
26 /// # Returns
27 ///
28 /// An [`Error`] wrapping [`RecognitionFailure::UnsupportedEncoding`].
29 #[must_use]
30 pub const fn unsupported_encoding() -> Self {
31 Self {
32 kind: ErrorKind::Recognition(RecognitionFailure::UnsupportedEncoding),
33 }
34 }
35
36 /// Creates a truncated-input error.
37 ///
38 /// # Returns
39 ///
40 /// An [`Error`] wrapping [`RecognitionFailure::Truncated`].
41 #[must_use]
42 pub const fn truncated() -> Self {
43 Self {
44 kind: ErrorKind::Recognition(RecognitionFailure::Truncated),
45 }
46 }
47
48 /// Creates a malformed-container error.
49 ///
50 /// # Returns
51 ///
52 /// An [`Error`] wrapping [`RecognitionFailure::MalformedContainer`].
53 #[must_use]
54 pub const fn malformed_container() -> Self {
55 Self {
56 kind: ErrorKind::Recognition(RecognitionFailure::MalformedContainer),
57 }
58 }
59
60 /// Creates a limit-exceeded error.
61 ///
62 /// # Returns
63 ///
64 /// An [`Error`] wrapping [`RecognitionFailure::LimitExceeded`].
65 #[must_use]
66 pub const fn limit_exceeded() -> Self {
67 Self {
68 kind: ErrorKind::Recognition(RecognitionFailure::LimitExceeded),
69 }
70 }
71
72 /// Creates a crypto-mismatch error.
73 ///
74 /// # Returns
75 ///
76 /// An [`Error`] wrapping [`RecognitionFailure::CryptoMismatch`].
77 #[must_use]
78 pub const fn crypto_mismatch() -> Self {
79 Self {
80 kind: ErrorKind::Recognition(RecognitionFailure::CryptoMismatch),
81 }
82 }
83
84 /// Creates a decompression error.
85 ///
86 /// # Returns
87 ///
88 /// An [`Error`] wrapping [`RecognitionFailure::CompressionError`].
89 #[must_use]
90 pub const fn compression_error() -> Self {
91 Self {
92 kind: ErrorKind::Recognition(RecognitionFailure::CompressionError),
93 }
94 }
95
96 /// Creates a token-decoding error.
97 ///
98 /// # Returns
99 ///
100 /// An [`Error`] wrapping [`RecognitionFailure::TokenError`].
101 #[must_use]
102 pub const fn token_error() -> Self {
103 Self {
104 kind: ErrorKind::Recognition(RecognitionFailure::TokenError),
105 }
106 }
107
108 /// Returns the recognition failure when this error represents one.
109 ///
110 /// # Returns
111 ///
112 /// `Some` with the wrapped [`RecognitionFailure`]; currently every [`Error`]
113 /// carries one, so this never returns `None`.
114 #[must_use]
115 pub const fn recognition_failure(&self) -> Option<RecognitionFailure> {
116 match self.kind {
117 ErrorKind::Recognition(failure) => Some(failure),
118 }
119 }
120}
121
122impl fmt::Display for Error {
123 /// Formats the error by delegating to its wrapped [`RecognitionFailure`].
124 ///
125 /// # Arguments
126 ///
127 /// * `f` - The formatter to write into.
128 ///
129 /// # Returns
130 ///
131 /// A [`fmt::Result`] propagating any formatter write error.
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 match self.kind {
134 ErrorKind::Recognition(failure) => write!(f, "{failure}"),
135 }
136 }
137}
138
139impl std::error::Error for Error {}
140
141/// Reasons an input could not be recognized or accepted as AutoIt.
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub enum RecognitionFailure {
144 /// No AutoIt container or payload markers were found.
145 NotRecognized,
146 /// AutoIt markers were found, but the encoding is not yet supported.
147 UnsupportedEncoding,
148 /// The outer container shape was recognized but malformed.
149 MalformedContainer,
150 /// The input ended before required AutoIt data could be read.
151 Truncated,
152 /// A configured extraction limit was exceeded.
153 LimitExceeded,
154 /// AutoIt data was recognized but a cryptographic validation step failed.
155 CryptoMismatch,
156 /// AutoIt data was recognized but decompression failed.
157 CompressionError,
158 /// AutoIt data was recognized but token decoding failed.
159 TokenError,
160}
161
162impl fmt::Display for RecognitionFailure {
163 /// Writes a human-readable description of the recognition failure.
164 ///
165 /// # Arguments
166 ///
167 /// * `f` - The formatter to write into.
168 ///
169 /// # Returns
170 ///
171 /// A [`fmt::Result`] propagating any formatter write error.
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 match self {
174 Self::NotRecognized => f.write_str("input is not recognized as AutoIt"),
175 Self::UnsupportedEncoding => f.write_str("AutoIt encoding is not supported"),
176 Self::MalformedContainer => f.write_str("AutoIt container is malformed"),
177 Self::Truncated => f.write_str("AutoIt input is truncated"),
178 Self::LimitExceeded => f.write_str("AutoIt extraction limit exceeded"),
179 Self::CryptoMismatch => f.write_str("AutoIt cryptographic validation failed"),
180 Self::CompressionError => f.write_str("AutoIt decompression failed"),
181 Self::TokenError => f.write_str("AutoIt token decoding failed"),
182 }
183 }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq)]
187enum ErrorKind {
188 Recognition(RecognitionFailure),
189}