golem_schema/schema/canonical/error.rs
1// Copyright 2024-2026 Golem Cloud
2//
3// Licensed under the Golem Source License v1.1 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::{Display, Formatter};
16
17/// Errors produced by the canonical text / JSON parsers.
18#[derive(Clone, Debug, PartialEq, Eq)]
19pub enum ParseError {
20 /// Input was empty where a non-empty value is required.
21 Empty,
22 /// Input had the wrong shape (free-form description).
23 BadFormat(String),
24 /// JSON object was missing a required field.
25 MissingField(&'static str),
26 /// JSON object carried an unexpected field name.
27 ExtraField(String),
28 /// JSON value (or field value) did not have the expected JSON type.
29 ///
30 /// Retained for sites that do not yet know which field they were reading;
31 /// new code should prefer [`ParseError::TypeField`].
32 Type(&'static str),
33 /// JSON value did not have the expected JSON type, with the field name
34 /// that produced the failure when applicable.
35 TypeField {
36 expected: &'static str,
37 field: Option<&'static str>,
38 },
39 /// Bytes were not valid UTF-8 when text was required.
40 InvalidUtf8,
41 /// Base64 payload could not be decoded.
42 InvalidBase64(String),
43 /// Number was out of the supported range.
44 OutOfRange(&'static str),
45 /// Embedded sub-value failed to parse.
46 Nested(Box<ParseError>),
47}
48
49impl Display for ParseError {
50 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51 match self {
52 ParseError::Empty => f.write_str("input is empty"),
53 ParseError::BadFormat(msg) => write!(f, "bad format: {msg}"),
54 ParseError::MissingField(name) => write!(f, "missing field: {name}"),
55 ParseError::ExtraField(name) => write!(f, "unexpected field: {name}"),
56 ParseError::Type(expected) => write!(f, "expected {expected}"),
57 ParseError::TypeField {
58 expected,
59 field: Some(name),
60 } => write!(f, "expected {expected} for field {name}"),
61 ParseError::TypeField {
62 expected,
63 field: None,
64 } => write!(f, "expected {expected}"),
65 ParseError::InvalidUtf8 => f.write_str("invalid UTF-8"),
66 ParseError::InvalidBase64(msg) => write!(f, "invalid base64: {msg}"),
67 ParseError::OutOfRange(what) => write!(f, "out of range: {what}"),
68 ParseError::Nested(inner) => write!(f, "{inner}"),
69 }
70 }
71}
72
73impl std::error::Error for ParseError {}