Skip to main content

qubit_json/encode/
json_encode_error_kind.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Defines stable categories for JSON encoding failures.
9
10use std::fmt;
11use std::str::FromStr;
12
13/// Represents the coarse category of a JSON encoding failure.
14///
15/// This exhaustive enum is the stable branching contract for strict JSON
16/// encoding. [`JsonEncodeError`](super::JsonEncodeError) keeps its internal
17/// representation private so new implementation details do not affect callers
18/// that branch through this category.
19///
20/// # Examples
21///
22/// ```
23/// use qubit_json::encode::JsonEncodeErrorKind;
24///
25/// let kind = "invalid_raw_json".parse::<JsonEncodeErrorKind>()?;
26/// assert_eq!(kind, JsonEncodeErrorKind::InvalidRawJson);
27/// # Ok::<(), &'static str>(())
28/// ```
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30pub enum JsonEncodeErrorKind {
31    /// Resource accounting rejected the value or output.
32    Budget,
33    /// A `RawValue` field did not contain valid JSON text.
34    InvalidRawJson,
35    /// Serde could not serialize the source value.
36    Serialize,
37    /// The external destination writer rejected output bytes.
38    Write,
39}
40
41impl fmt::Display for JsonEncodeErrorKind {
42    /// Writes the stable snake-case category name.
43    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44        formatter.write_str(match self {
45            Self::Budget => "budget",
46            Self::InvalidRawJson => "invalid_raw_json",
47            Self::Serialize => "serialize",
48            Self::Write => "write",
49        })
50    }
51}
52
53impl FromStr for JsonEncodeErrorKind {
54    type Err = &'static str;
55
56    /// Parses a stable category name without ASCII case sensitivity.
57    fn from_str(value: &str) -> Result<Self, Self::Err> {
58        if value.eq_ignore_ascii_case("budget") {
59            Ok(Self::Budget)
60        } else if value.eq_ignore_ascii_case("invalid_raw_json") {
61            Ok(Self::InvalidRawJson)
62        } else if value.eq_ignore_ascii_case("serialize") {
63            Ok(Self::Serialize)
64        } else if value.eq_ignore_ascii_case("write") {
65            Ok(Self::Write)
66        } else {
67            Err("unknown JsonEncodeErrorKind")
68        }
69    }
70}