Skip to main content

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 {}