qubit_json/encode/jcs_working_memory_error.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 the safe error returned when JCS working memory exceeds its limit.
9
10use std::error::Error;
11use std::fmt;
12
13/// Reports when JCS rendering needs more auxiliary memory than the configured
14/// limit.
15///
16/// The error records both byte counts without exposing the rendered value.
17///
18/// # Examples
19///
20/// ```
21/// use qubit_budget::json::JsonEncodeLimits;
22/// use qubit_json::encode::JcsEncoder;
23///
24/// let limits: JsonEncodeLimits = JsonEncodeLimits::new();
25/// let mut encoder = JcsEncoder::with_limits(limits, 0);
26/// let error = encoder
27/// .to_vec(&serde_json::json!({"key": "value"}))
28/// .expect_err("zero working memory cannot render an object");
29/// let memory_error = error
30/// .working_memory_error()
31/// .expect("the failure is caused by the working memory limit");
32/// assert_eq!(memory_error.limit(), 0);
33/// assert!(memory_error.requested() > memory_error.limit());
34/// ```
35#[must_use]
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37pub struct JcsWorkingMemoryError {
38 /// Maximum auxiliary memory available to the JCS renderer, in bytes.
39 limit: usize,
40 /// Auxiliary memory required by the rejected rendering request, in bytes.
41 requested: usize,
42}
43
44impl JcsWorkingMemoryError {
45 /// Creates a working memory error with the configured limit and request.
46 ///
47 /// # Parameters
48 ///
49 /// * `limit` is the maximum auxiliary memory available to the renderer.
50 /// * `requested` is the auxiliary memory required by the rejected request.
51 ///
52 /// # Returns
53 ///
54 /// The error containing both byte counts.
55 #[inline]
56 pub(crate) const fn new(limit: usize, requested: usize) -> Self {
57 Self { limit, requested }
58 }
59
60 /// Returns the configured working memory limit in bytes.
61 ///
62 /// # Returns
63 ///
64 /// The maximum auxiliary memory available to the renderer.
65 #[must_use]
66 #[inline]
67 pub const fn limit(&self) -> usize {
68 self.limit
69 }
70
71 /// Returns the requested working memory in bytes.
72 ///
73 /// # Returns
74 ///
75 /// The auxiliary memory required by the rejected request.
76 #[must_use]
77 #[inline]
78 pub const fn requested(&self) -> usize {
79 self.requested
80 }
81}
82
83impl fmt::Display for JcsWorkingMemoryError {
84 /// Formats the configured limit and rejected request for diagnostics.
85 ///
86 /// # Parameters
87 ///
88 /// * `formatter` is the destination receiving the diagnostic text.
89 ///
90 /// # Returns
91 ///
92 /// `Ok(())` when formatting succeeds, or a formatting error if the
93 /// destination rejects the output.
94 ///
95 /// # Errors
96 ///
97 /// Returns the formatting error from the destination when it rejects
98 /// output.
99 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
100 write!(
101 formatter,
102 "JCS working memory limit exceeded (limit: {}, requested: {})",
103 self.limit, self.requested
104 )
105 }
106}
107
108impl Error for JcsWorkingMemoryError {}