vest_lib/core/exec/
error.rs1use core::fmt;
3
4#[cfg(feature = "error-trace")]
5use alloc::vec::Vec;
6
7use vstd::prelude::*;
8
9verus! {
10
11#[derive(Debug, PartialEq, Eq)]
19pub struct ParseError {
20 pub kind: ParseErrorKind,
22 pub failed_format: Option<&'static str>,
24 #[cfg(feature = "error-trace")]
26 pub format_stack: Vec<&'static str>,
27}
28
29impl Clone for ParseError {
30 fn clone(&self) -> Self {
31 Self {
32 kind: self.kind.clone(),
33 failed_format: self.failed_format,
34 #[cfg(feature = "error-trace")]
35 format_stack: self.format_stack.clone(),
36 }
37 }
38}
39
40impl ParseError {
41 pub fn new(kind: ParseErrorKind) -> (e: Self)
43 ensures
44 e.kind == kind,
45 {
46 Self {
47 kind,
48 failed_format: None,
49 #[cfg(feature = "error-trace")]
50 format_stack: Vec::new(),
51 }
52 }
53
54 pub fn push_format(self, current_format: &'static str) -> Self {
60 let mut err = self;
61 if err.failed_format.is_none() {
62 err.failed_format = Some(current_format);
63 }
64 #[cfg(feature = "error-trace")]
65 {
66 err.format_stack.push(current_format);
67 }
68 err
69 }
70
71 pub fn format_trace(&self) -> &[&'static str] {
73 #[cfg(feature = "error-trace")]
74 { self.format_stack.as_slice() }
75 #[cfg(not(feature = "error-trace"))]
76 { &[] }
77 }
78}
79
80impl ParseError {
81 pub fn unexpected_eof() -> (e: Self)
83 ensures
84 e.kind == ParseErrorKind::UnexpectedEof,
85 {
86 Self::new(ParseErrorKind::UnexpectedEof)
87 }
88
89 pub fn expecting_eof() -> Self {
91 Self::new(ParseErrorKind::ExpectingEof)
92 }
93
94 pub fn invalid_tag() -> Self {
96 Self::new(ParseErrorKind::InvalidTag)
97 }
98
99 pub fn invalid_choice() -> Self {
101 Self::new(ParseErrorKind::InvalidChoice)
102 }
103
104 pub fn invalid_length() -> Self {
106 Self::new(ParseErrorKind::InvalidLength)
107 }
108
109 pub fn length_mismatch() -> Self {
111 Self::new(ParseErrorKind::LengthMismatch)
112 }
113
114 pub fn predicate_failed() -> Self {
116 Self::new(ParseErrorKind::PredicateFailed)
117 }
118
119 pub fn cond_rejected() -> Self {
121 Self::new(ParseErrorKind::CondRejected)
122 }
123
124 pub fn non_canonical() -> Self {
126 Self::new(ParseErrorKind::NonCanonical)
127 }
128
129 pub fn overflow() -> (e: Self)
131 ensures
132 e.kind == ParseErrorKind::Overflow,
133 {
134 Self::new(ParseErrorKind::Overflow)
135 }
136
137 pub fn recursion_limit_exceeded() -> Self {
139 Self::new(ParseErrorKind::RecursionLimitExceeded)
140 }
141
142 pub fn custom(msg: &'static str) -> Self {
144 Self::new(ParseErrorKind::Custom(msg))
145 }
146}
147
148} impl fmt::Display for ParseError {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 let format_trace = self.format_trace();
152 if !format_trace.is_empty() {
153 write!(f, "{} while parsing format stack ", self.kind)?;
154 for (i, format_name) in format_trace.iter().rev().enumerate() {
155 if i > 0 {
156 f.write_str(" -> ")?;
157 }
158 write!(f, "`{}`", format_name)?;
159 }
160 Ok(())
161 } else {
162 match self.failed_format {
163 Some(current_format) => {
164 write!(f, "{} while parsing format `{}`", self.kind, current_format)
165 }
166 None => write!(f, "{}", self.kind),
167 }
168 }
169 }
170}
171
172#[cfg(feature = "std")]
173impl std::error::Error for ParseError {}
174
175verus! {
176
177#[derive(Debug, Copy, PartialEq, Eq)]
179pub enum ParseErrorKind {
180 UnexpectedEof,
182 ExpectingEof,
184 InvalidTag,
186 InvalidChoice,
188 InvalidLength,
190 LengthMismatch,
192 PredicateFailed,
194 CondRejected,
196 NonCanonical,
198 Overflow,
200 RecursionLimitExceeded,
202 Custom(&'static str),
204}
205
206impl Clone for ParseErrorKind {
207 fn clone(&self) -> Self {
208 *self
209 }
210}
211
212} impl fmt::Display for ParseErrorKind {
214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 match self {
216 ParseErrorKind::UnexpectedEof => {
217 f.write_str("input ended before the format could finish parsing")
218 }
219 ParseErrorKind::ExpectingEof => f.write_str("unexpected trailing input"),
220 ParseErrorKind::InvalidTag => {
221 f.write_str("tag or discriminant did not match the format")
222 }
223 ParseErrorKind::InvalidChoice => f.write_str("input did not match any choice branch"),
224 ParseErrorKind::InvalidLength => {
225 f.write_str("length field is outside the format's valid range")
226 }
227 ParseErrorKind::LengthMismatch => {
228 f.write_str("a length-delimited parser did not consume the declared length")
229 }
230 ParseErrorKind::PredicateFailed => {
231 f.write_str("parsed value failed a refinement predicate")
232 }
233 ParseErrorKind::CondRejected => f.write_str("conditional format rejected this branch"),
234 ParseErrorKind::NonCanonical => f.write_str("non-canonical encoding"),
235 ParseErrorKind::Overflow => f.write_str("integer or size computation overflowed"),
236 ParseErrorKind::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
237 ParseErrorKind::Custom(s) => f.write_str(s),
238 }
239 }
240}