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 ///
45 /// # Parameters
46 ///
47 /// * `formatter` - Destination receiving the category name.
48 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49 formatter.write_str(match self {
50 Self::Budget => "budget",
51 Self::InvalidRawJson => "invalid_raw_json",
52 Self::Serialize => "serialize",
53 Self::Write => "write",
54 })
55 }
56}
57
58impl FromStr for JsonEncodeErrorKind {
59 /// Static message returned when parsing an unrecognized category name.
60 type Err = &'static str;
61
62 /// Parses a stable category name without ASCII case sensitivity.
63 ///
64 /// # Parameters
65 ///
66 /// * `value` - Case-insensitive snake-case category name.
67 fn from_str(value: &str) -> Result<Self, Self::Err> {
68 if value.eq_ignore_ascii_case("budget") {
69 Ok(Self::Budget)
70 } else if value.eq_ignore_ascii_case("invalid_raw_json") {
71 Ok(Self::InvalidRawJson)
72 } else if value.eq_ignore_ascii_case("serialize") {
73 Ok(Self::Serialize)
74 } else if value.eq_ignore_ascii_case("write") {
75 Ok(Self::Write)
76 } else {
77 Err("unknown JsonEncodeErrorKind")
78 }
79 }
80}