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#[must_use]
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
31pub enum JsonEncodeErrorKind {
32    /// Resource accounting rejected the value or output.
33    Budget,
34    /// A `RawValue` field did not contain valid JSON text.
35    InvalidRawJson,
36    /// Serde could not serialize the source value.
37    Serialize,
38    /// The external destination writer rejected output bytes.
39    Write,
40}
41
42impl fmt::Display for JsonEncodeErrorKind {
43    /// Writes the stable snake-case category name.
44    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
45        formatter.write_str(match self {
46            Self::Budget => "budget",
47            Self::InvalidRawJson => "invalid_raw_json",
48            Self::Serialize => "serialize",
49            Self::Write => "write",
50        })
51    }
52}
53
54impl FromStr for JsonEncodeErrorKind {
55    type Err = &'static str;
56
57    /// Parses a stable category name without ASCII case sensitivity.
58    fn from_str(value: &str) -> Result<Self, Self::Err> {
59        if value.eq_ignore_ascii_case("budget") {
60            Ok(Self::Budget)
61        } else if value.eq_ignore_ascii_case("invalid_raw_json") {
62            Ok(Self::InvalidRawJson)
63        } else if value.eq_ignore_ascii_case("serialize") {
64            Ok(Self::Serialize)
65        } else if value.eq_ignore_ascii_case("write") {
66            Ok(Self::Write)
67        } else {
68            Err("unknown JsonEncodeErrorKind")
69        }
70    }
71}