Skip to main content

qubit_budget/resource/error/
budget_group_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 failures from atomic grouped budget consumption.
9
10use std::fmt::Debug;
11
12use thiserror::Error;
13
14use crate::resource::InsufficientBudgetError;
15
16/// Failure returned by an atomic grouped budget consumption.
17///
18/// The index identifies the first budget, in caller-provided order, that
19/// rejected the request. No member of the group is charged when this error is
20/// returned.
21///
22/// # Type Parameters
23///
24/// * `R` - Caller-defined resource identity retained by limits and errors.
25/// * `Q` - Exact unsigned quantity used for measurements and accounting.
26///
27/// # Examples
28///
29/// ```
30/// use qubit_budget::ResourceBudget;
31///
32/// let mut first = ResourceBudget::new("first", 2_u64);
33/// let mut second = ResourceBudget::new("second", 1_u64);
34/// let error = ResourceBudget::try_consume_group(&mut [&mut first, &mut second], 2)
35///     .expect_err("the second budget should reject the charge");
36/// assert_eq!(error.index(), 1);
37/// assert_eq!(first.remaining(), 2);
38/// ```
39#[must_use]
40#[derive(Debug, Error, Clone, PartialEq, Eq)]
41#[error("budget group member {index} rejected consumption: {source}")]
42pub struct BudgetGroupError<R, Q = u64>
43where
44    Q: Copy + Debug,
45{
46    /// Zero-based index of the first rejecting budget.
47    index: usize,
48
49    /// Structured failure returned by that budget.
50    #[source]
51    source: InsufficientBudgetError<R, Q>,
52}
53
54impl<R, Q> BudgetGroupError<R, Q>
55where
56    Q: Copy + Debug,
57{
58    /// Creates a grouped failure for the first rejecting budget.
59    ///
60    /// # Parameters
61    ///
62    /// * `index` - Zero-based position associated with the operation.
63    /// * `source` - Underlying failure retained as the error source.
64    ///
65    /// # Returns
66    ///
67    /// Creates a grouped failure for the first rejecting budget.
68    pub(crate) const fn new(index: usize, source: InsufficientBudgetError<R, Q>) -> Self {
69        Self { index, source }
70    }
71
72    /// Returns the zero-based index of the first rejecting budget.
73    ///
74    /// # Returns
75    ///
76    /// Returns the zero-based index of the first rejecting budget.
77    #[inline(always)]
78    #[must_use]
79    pub const fn index(&self) -> usize {
80        self.index
81    }
82
83    /// Returns the structured failure from the rejecting budget.
84    ///
85    /// # Returns
86    ///
87    /// Returns the structured failure from the rejecting budget.
88    #[inline(always)]
89    pub const fn source_error(&self) -> &InsufficientBudgetError<R, Q> {
90        &self.source
91    }
92
93    /// Consumes this error and returns the rejecting budget's failure.
94    ///
95    /// # Returns
96    ///
97    /// Consumes this error and returns the rejecting budget's failure.
98    #[inline(always)]
99    pub fn into_source_error(self) -> InsufficientBudgetError<R, Q> {
100        self.source
101    }
102}