1use std::fmt;
13
14pub type Result<T> = std::result::Result<T, Error>;
16
17#[allow(missing_docs)]
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum Error {
23 Magic,
26 VersionMajor(u16),
28 VersionMinor(u16),
30 HeaderTruncated,
32 HeaderSize(u8),
34 UnknownFlags(u16),
36 ReservedNonZero { section: &'static str, offset: u64 },
38 Offset { section: &'static str, offset: u64 },
41 Truncated { needed: u64, found: u64 },
43 TrailingBytes { at: u64 },
45 Count { field: &'static str, value: u64 },
48 Padding { offset: u64 },
50 HashMismatch,
52 DialectMismatch(u64),
54 NotCanonical,
56
57 StringRef(u32),
60 NodeRef(u32),
62 Node { id: u32, reason: &'static str },
64 Utf8 { offset: u64 },
66 UnknownUnit(u32),
68 UnitRef(u32),
70 Type { id: u32, reason: &'static str },
72 Edge { from: u32, to: u32 },
74 Annotation { id: u32, reason: &'static str },
76 Provenance(&'static str),
78 Extension { tag: u64, reason: &'static str },
80 Blob { id: u32, reason: &'static str },
82 SecretEntry(u32),
84 DuplicateField { node: u32 },
86 DuplicateBinding,
88 Cycle { node: u32 },
90 Depth { limit: u32 },
92
93 Limit { kind: &'static str, limit: u64 },
96 InvalidArgument(&'static str),
98 Evaluation(&'static str),
101
102 Encode(&'static str),
105 EncodeDangling(u32),
107 TooLarge,
109
110 StreamMagic,
113 StreamVersion(u8),
115 StreamFrameLen { declared: u32, available: u64 },
117 StreamFrameKind(u8),
119 StreamSequence { expected: u64, found: u64 },
121 StreamState(&'static str),
123 StreamHashMismatch,
125 StreamDelta(&'static str),
127 StreamUnterminated,
129}
130
131impl Error {
132 pub const fn code(&self) -> &'static str {
134 match self {
135 Error::Magic => "infinity/magic",
136 Error::VersionMajor(_) => "infinity/version-major",
137 Error::VersionMinor(_) => "infinity/version-minor",
138 Error::HeaderTruncated => "infinity/header-truncated",
139 Error::HeaderSize(_) => "infinity/header-size",
140 Error::UnknownFlags(_) => "infinity/flags",
141 Error::ReservedNonZero { .. } => "infinity/reserved",
142 Error::Offset { .. } => "infinity/offset",
143 Error::Truncated { .. } => "infinity/truncated",
144 Error::TrailingBytes { .. } => "infinity/trailing-bytes",
145 Error::Count { .. } => "infinity/count",
146 Error::Padding { .. } => "infinity/padding",
147 Error::HashMismatch => "infinity/hash-mismatch",
148 Error::DialectMismatch(_) => "infinity/dialect",
149 Error::NotCanonical => "infinity/not-canonical",
150 Error::StringRef(_) => "infinity/string-ref",
151 Error::NodeRef(_) => "infinity/node-ref",
152 Error::Node { .. } => "infinity/node",
153 Error::Utf8 { .. } => "infinity/utf8",
154 Error::UnknownUnit(_) => "infinity/unknown-unit",
155 Error::UnitRef(_) => "infinity/unit-ref",
156 Error::Type { .. } => "infinity/type",
157 Error::Edge { .. } => "infinity/edge",
158 Error::Annotation { .. } => "infinity/annotation",
159 Error::Provenance(_) => "infinity/provenance",
160 Error::Extension { .. } => "infinity/extension",
161 Error::Blob { .. } => "infinity/blob",
162 Error::SecretEntry(_) => "infinity/secret-entry",
163 Error::DuplicateField { .. } => "infinity/duplicate-field",
164 Error::DuplicateBinding => "infinity/duplicate-binding",
165 Error::Cycle { .. } => "infinity/cycle",
166 Error::Depth { .. } => "infinity/depth",
167 Error::Limit { .. } => "infinity/limit",
168 Error::InvalidArgument(_) => "infinity/invalid-argument",
169 Error::Evaluation(_) => "infinity/evaluation",
170 Error::Encode(_) => "infinity/encode",
171 Error::EncodeDangling(_) => "infinity/encode-dangling",
172 Error::TooLarge => "infinity/too-large",
173 Error::StreamMagic => "infinity/stream-magic",
174 Error::StreamVersion(_) => "infinity/stream-version",
175 Error::StreamFrameLen { .. } => "infinity/stream-frame-len",
176 Error::StreamFrameKind(_) => "infinity/stream-frame-kind",
177 Error::StreamSequence { .. } => "infinity/stream-sequence",
178 Error::StreamState(_) => "infinity/stream-state",
179 Error::StreamHashMismatch => "infinity/stream-hash",
180 Error::StreamDelta(_) => "infinity/stream-delta",
181 Error::StreamUnterminated => "infinity/stream-unterminated",
182 }
183 }
184
185 pub const fn is_fatal(&self) -> bool {
190 !matches!(self, Error::InvalidArgument(_))
191 }
192}
193
194impl fmt::Display for Error {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 match self {
199 Error::Magic => write!(f, "not an Active Infinity buffer (bad magic)"),
200 Error::VersionMajor(v) => write!(f, "unsupported major version {v}"),
201 Error::VersionMinor(v) => write!(f, "unsupported minor version {v}"),
202 Error::HeaderTruncated => write!(f, "buffer shorter than the fixed header"),
203 Error::HeaderSize(n) => write!(f, "unsupported header size {n}"),
204 Error::UnknownFlags(bits) => write!(f, "unknown header flag bits {bits:#06x}"),
205 Error::ReservedNonZero { section, offset } => {
206 write!(f, "reserved field in {section} is non-zero at {offset}")
207 }
208 Error::Offset { section, offset } => {
209 write!(f, "invalid {section} offset/range at {offset}")
210 }
211 Error::Truncated { needed, found } => {
212 write!(f, "truncated buffer: need {needed} bytes, found {found}")
213 }
214 Error::TrailingBytes { at } => write!(f, "trailing bytes after {at}"),
215 Error::Count { field, value } => write!(f, "invalid {field} count {value}"),
216 Error::Padding { offset } => write!(f, "non-zero padding at {offset}"),
217 Error::HashMismatch => write!(f, "content hash mismatch"),
218 Error::DialectMismatch(h) => write!(f, "dialect hash {h:#018x} not supported"),
219 Error::NotCanonical => write!(f, "buffer is not in canonical form"),
220 Error::StringRef(id) => write!(f, "dangling string reference {id}"),
221 Error::NodeRef(id) => write!(f, "dangling node reference {id}"),
222 Error::Node { id, reason } => write!(f, "node {id} is invalid: {reason}"),
223 Error::Utf8 { offset } => write!(f, "invalid UTF-8 in string heap at {offset}"),
224 Error::UnknownUnit(d) => write!(f, "unknown unit discriminant {d}"),
225 Error::UnitRef(id) => write!(f, "dangling unit reference {id}"),
226 Error::Type { id, reason } => write!(f, "type {id} is invalid: {reason}"),
227 Error::Edge { from, to } => write!(f, "invalid edge {from} -> {to}"),
228 Error::Annotation { id, reason } => write!(f, "annotation {id} is invalid: {reason}"),
229 Error::Provenance(reason) => write!(f, "provenance block is invalid: {reason}"),
230 Error::Extension { tag, reason } => {
231 write!(f, "extension {tag} is invalid: {reason}")
232 }
233 Error::Blob { id, reason } => write!(f, "blob {id} is invalid: {reason}"),
234 Error::SecretEntry(id) => write!(f, "secret entry {id} is invalid"),
235 Error::DuplicateField { node } => write!(f, "table node {node} repeats a field name"),
236 Error::DuplicateBinding => write!(f, "duplicate binding name"),
237 Error::Cycle { node } => write!(
238 f,
239 "dependency cycle: node {node} is on a cycle or depends on one"
240 ),
241 Error::Depth { limit } => write!(f, "nesting deeper than {limit}"),
242 Error::Limit { kind, limit } => write!(f, "{kind} limit {limit} exceeded"),
243 Error::InvalidArgument(what) => write!(f, "invalid argument: {what}"),
244 Error::Evaluation(code) => write!(f, "Active evaluation failed: {code}"),
245 Error::Encode(what) => write!(f, "cannot encode module: {what}"),
246 Error::EncodeDangling(id) => write!(f, "cannot encode: dangling node {id}"),
247 Error::TooLarge => write!(f, "module exceeds the 4 GiB addressable image"),
248 Error::StreamMagic => write!(f, "not an Active Infinity stream frame"),
249 Error::StreamVersion(v) => write!(f, "unsupported stream frame version {v}"),
250 Error::StreamFrameLen {
251 declared,
252 available,
253 } => {
254 write!(
255 f,
256 "stream frame declares {declared} bytes, {available} available"
257 )
258 }
259 Error::StreamFrameKind(k) => write!(f, "unknown stream frame kind {k}"),
260 Error::StreamSequence { expected, found } => {
261 write!(
262 f,
263 "stream frame out of order: expected {expected}, got {found}"
264 )
265 }
266 Error::StreamState(what) => write!(f, "stream state error: {what}"),
267 Error::StreamHashMismatch => write!(f, "streamed module hash mismatch"),
268 Error::StreamDelta(what) => write!(f, "delta cannot be applied: {what}"),
269 Error::StreamUnterminated => write!(f, "stream ended without an end frame"),
270 }
271 }
272}
273
274impl std::error::Error for Error {}
275
276impl From<std::str::Utf8Error> for Error {
277 fn from(_: std::str::Utf8Error) -> Self {
278 Error::Utf8 { offset: 0 }
279 }
280}