Skip to main content

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