Skip to main content

qubit_budget/resource/error/
limit_exceeded_error.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Defines point-limit failures for finite resource constraints.
9
10use std::fmt::Debug;
11
12use thiserror::Error;
13
14use crate::resource::Observation;
15
16/// Structured facts for a point measurement that exceeded its maximum.
17///
18/// # Type Parameters
19///
20/// * `R` - Caller-defined resource value retained for diagnostics.
21/// * `Q` - Copyable measurement value used by the failed constraint.
22///
23/// # Examples
24///
25/// ```
26/// use qubit_budget::LimitExceededError;
27/// use qubit_budget::Observation;
28///
29/// let error = LimitExceededError::exact("depth", 3_u64, 2);
30/// assert_eq!(error.observation(), Observation::Exact(3));
31/// assert_eq!(error.maximum(), 2);
32/// ```
33#[must_use]
34#[derive(Debug, Error, Clone, PartialEq, Eq)]
35#[error("resource {resource:?} measured {observed}, exceeding the maximum of {maximum:?}")]
36pub struct LimitExceededError<R, Q = u64>
37where
38    Q: Copy + Debug,
39{
40    /// Resource associated with the failed point check.
41    pub resource: R,
42    /// Observed point measurement or safe lower bound.
43    pub observed: Observation<Q>,
44    /// Configured inclusive point maximum.
45    pub maximum: Q,
46}
47
48impl<R, Q> LimitExceededError<R, Q>
49where
50    Q: Copy + Debug,
51{
52    /// Creates a failure from an exact point measurement.
53    ///
54    /// # Parameters
55    ///
56    /// * `resource` - Resource associated with the failed point check.
57    /// * `observed` - Exact measurement that exceeded `maximum`.
58    /// * `maximum` - Configured inclusive point maximum.
59    ///
60    /// # Returns
61    ///
62    /// A structured failure containing an [`Observation::Exact`] measurement.
63    #[inline(always)]
64    pub const fn exact(resource: R, observed: Q, maximum: Q) -> Self {
65        Self {
66            resource,
67            observed: Observation::Exact(observed),
68            maximum,
69        }
70    }
71
72    /// Creates a failure from a safe lower bound for a point measurement.
73    ///
74    /// # Parameters
75    ///
76    /// * `resource` - Resource associated with the failed point check.
77    /// * `lower_bound` - Proven lower bound that exceeded `maximum`.
78    /// * `maximum` - Configured inclusive point maximum.
79    ///
80    /// # Returns
81    ///
82    /// A structured failure containing an [`Observation::AtLeast`]
83    /// measurement.
84    #[inline(always)]
85    pub const fn at_least(resource: R, lower_bound: Q, maximum: Q) -> Self {
86        Self {
87            resource,
88            observed: Observation::AtLeast(lower_bound),
89            maximum,
90        }
91    }
92
93    /// Returns the resource associated with this failure.
94    ///
95    /// # Returns
96    ///
97    /// Returns the resource associated with this failure.
98    #[must_use]
99    #[inline(always)]
100    pub const fn resource(&self) -> &R {
101        &self.resource
102    }
103
104    /// Consumes this error and returns its associated resource.
105    ///
106    /// # Returns
107    ///
108    /// Consumes this error and returns its associated resource.
109    #[must_use]
110    #[inline(always)]
111    pub fn into_resource(self) -> R {
112        self.resource
113    }
114
115    /// Returns the observed point measurement or safe lower bound.
116    ///
117    /// # Returns
118    ///
119    /// Returns the observed point measurement or safe lower bound.
120    #[must_use]
121    #[inline(always)]
122    pub const fn observation(&self) -> Observation<Q> {
123        self.observed
124    }
125
126    /// Returns the exact point measurement when the observation is exact.
127    ///
128    /// # Returns
129    ///
130    /// Returns the exact point measurement when the observation is exact.
131    ///
132    /// `None` indicates that the observation is only a lower bound.
133    #[must_use]
134    #[inline(always)]
135    pub const fn exact_observed(&self) -> Option<Q> {
136        match self.observed {
137            Observation::Exact(value) => Some(value),
138            Observation::AtLeast(_) => None,
139        }
140    }
141
142    /// Returns the safe lower bound of the observed point measurement.
143    ///
144    /// # Returns
145    ///
146    /// Returns the safe lower bound of the observed point measurement.
147    #[must_use]
148    #[inline(always)]
149    pub const fn observed_lower_bound(&self) -> Q {
150        self.observed.lower_bound()
151    }
152
153    /// Returns the configured inclusive point maximum.
154    ///
155    /// # Returns
156    ///
157    /// Returns the configured inclusive point maximum.
158    #[must_use]
159    #[inline(always)]
160    pub const fn maximum(&self) -> Q {
161        self.maximum
162    }
163}