11use std:: time;
22
3- use super :: std_messages:: { BadRequest , DebugInfo , FieldViolation , RetryInfo } ;
3+ use super :: std_messages:: {
4+ BadRequest , DebugInfo , FieldViolation , QuotaFailure , QuotaViolation , RetryInfo ,
5+ } ;
46
57pub ( crate ) mod vec;
68
@@ -17,6 +19,9 @@ pub struct ErrorDetails {
1719 /// This field stores [`DebugInfo`] data, if any.
1820 pub ( crate ) debug_info : Option < DebugInfo > ,
1921
22+ /// This field stores [`QuotaFailure`] data, if any.
23+ pub ( crate ) quota_failure : Option < QuotaFailure > ,
24+
2025 /// This field stores [`BadRequest`] data, if any.
2126 pub ( crate ) bad_request : Option < BadRequest > ,
2227}
@@ -35,6 +40,7 @@ impl ErrorDetails {
3540 ErrorDetails {
3641 retry_info : None ,
3742 debug_info : None ,
43+ quota_failure : None ,
3844 bad_request : None ,
3945 }
4046 }
@@ -76,6 +82,46 @@ impl ErrorDetails {
7682 }
7783 }
7884
85+ /// Generates an [`ErrorDetails`] struct with [`QuotaFailure`] details and
86+ /// remaining fields set to `None`.
87+ ///
88+ /// # Examples
89+ ///
90+ /// ```
91+ /// use tonic_types::{ErrorDetails, QuotaViolation};
92+ ///
93+ /// let err_details = ErrorDetails::with_quota_failure(vec![
94+ /// QuotaViolation::new("subject 1", "description 1"),
95+ /// QuotaViolation::new("subject 2", "description 2"),
96+ /// ]);
97+ /// ```
98+ pub fn with_quota_failure ( violations : Vec < QuotaViolation > ) -> Self {
99+ ErrorDetails {
100+ quota_failure : Some ( QuotaFailure :: new ( violations) ) ,
101+ ..ErrorDetails :: new ( )
102+ }
103+ }
104+
105+ /// Generates an [`ErrorDetails`] struct with [`QuotaFailure`] details (one
106+ /// [`QuotaViolation`] set) and remaining fields set to `None`.
107+ ///
108+ /// # Examples
109+ ///
110+ /// ```
111+ /// use tonic_types::{ErrorDetails};
112+ ///
113+ /// let err_details = ErrorDetails::with_quota_failure_violation("subject", "description");
114+ /// ```
115+ pub fn with_quota_failure_violation (
116+ subject : impl Into < String > ,
117+ description : impl Into < String > ,
118+ ) -> Self {
119+ ErrorDetails {
120+ quota_failure : Some ( QuotaFailure :: with_violation ( subject, description) ) ,
121+ ..ErrorDetails :: new ( )
122+ }
123+ }
124+
79125 /// Generates an [`ErrorDetails`] struct with [`BadRequest`] details and
80126 /// remaining fields set to `None`.
81127 ///
@@ -129,6 +175,11 @@ impl ErrorDetails {
129175 self . debug_info . clone ( )
130176 }
131177
178+ /// Get [`QuotaFailure`] details, if any
179+ pub fn quota_failure ( & self ) -> Option < QuotaFailure > {
180+ self . quota_failure . clone ( )
181+ }
182+
132183 /// Get [`BadRequest`] details, if any
133184 pub fn bad_request ( & self ) -> Option < BadRequest > {
134185 self . bad_request . clone ( )
@@ -175,6 +226,78 @@ impl ErrorDetails {
175226 self
176227 }
177228
229+ /// Set [`QuotaFailure`] details. Can be chained with other `.set_` and
230+ /// `.add_` [`ErrorDetails`] methods.
231+ ///
232+ /// # Examples
233+ ///
234+ /// ```
235+ /// use tonic_types::{ErrorDetails, QuotaViolation};
236+ ///
237+ /// let mut err_details = ErrorDetails::new();
238+ ///
239+ /// err_details.set_quota_failure(vec![
240+ /// QuotaViolation::new("subject 1", "description 1"),
241+ /// QuotaViolation::new("subject 2", "description 2"),
242+ /// ]);
243+ /// ```
244+ pub fn set_quota_failure ( & mut self , violations : Vec < QuotaViolation > ) -> & mut Self {
245+ self . quota_failure = Some ( QuotaFailure :: new ( violations) ) ;
246+ self
247+ }
248+
249+ /// Adds a [`QuotaViolation`] to [`QuotaFailure`] details. Sets
250+ /// [`QuotaFailure`] details if it is not set yet. Can be chained with
251+ /// other `.set_` and `.add_` [`ErrorDetails`] methods.
252+ ///
253+ /// # Examples
254+ ///
255+ /// ```
256+ /// use tonic_types::{ErrorDetails};
257+ ///
258+ /// let mut err_details = ErrorDetails::new();
259+ ///
260+ /// err_details.add_quota_failure_violation("subject", "description");
261+ /// ```
262+ pub fn add_quota_failure_violation (
263+ & mut self ,
264+ subject : impl Into < String > ,
265+ description : impl Into < String > ,
266+ ) -> & mut Self {
267+ match & mut self . quota_failure {
268+ Some ( quota_failure) => {
269+ quota_failure. add_violation ( subject, description) ;
270+ }
271+ None => {
272+ self . quota_failure = Some ( QuotaFailure :: with_violation ( subject, description) ) ;
273+ }
274+ } ;
275+ self
276+ }
277+
278+ /// Returns `true` if [`QuotaFailure`] is set and its `violations` vector
279+ /// is not empty, otherwise returns `false`.
280+ ///
281+ /// # Examples
282+ ///
283+ /// ```
284+ /// use tonic_types::{ErrorDetails};
285+ ///
286+ /// let mut err_details = ErrorDetails::with_quota_failure(vec![]);
287+ ///
288+ /// assert_eq!(err_details.has_quota_failure_violations(), false);
289+ ///
290+ /// err_details.add_quota_failure_violation("subject", "description");
291+ ///
292+ /// assert_eq!(err_details.has_quota_failure_violations(), true);
293+ /// ```
294+ pub fn has_quota_failure_violations ( & self ) -> bool {
295+ if let Some ( quota_failure) = & self . quota_failure {
296+ return !quota_failure. violations . is_empty ( ) ;
297+ }
298+ false
299+ }
300+
178301 /// Set [`BadRequest`] details. Can be chained with other `.set_` and
179302 /// `.add_` [`ErrorDetails`] methods.
180303 ///
0 commit comments