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