Skip to main content

qcs_api_client_openapi/apis/
account_api.rs

1// Copyright 2026 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Rigetti QCS API
17 *
18 * # Introduction  This is the documentation for the Rigetti QCS HTTP API.  You can find out more about Rigetti at [https://rigetti.com](https://rigetti.com), and also interact with QCS via the web at [https://qcs.rigetti.com](https://qcs.rigetti.com).  This API is documented in **OpenAPI format** and so is compatible with the dozens of language-specific client generators available [here](https://github.com/OpenAPITools/openapi-generator) and elsewhere on the web.  # Principles  This API follows REST design principles where appropriate, and otherwise an HTTP RPC paradigm. We adhere to the Google [API Improvement Proposals](https://google.aip.dev/general) where reasonable to provide a consistent, intuitive developer experience. HTTP response codes match their specifications, and error messages fit a common format.  # Authentication  All access to the QCS API requires OAuth2 authentication provided by Okta. You can request access [here](https://www.rigetti.com/get-quantum). Once you have a user account, you can download your access token from QCS [here](https://qcs.rigetti.com/auth/token).   That access token is valid for 24 hours after issuance. The value of `access_token` within the JSON file is the token used for authentication (don't use the entire JSON file).  Authenticate requests using the `Authorization` header and a `Bearer` prefix:  ``` curl --header \"Authorization: Bearer eyJraW...Iow\" ```  # Quantum Processor Access  Access to the quantum processors themselves is not yet provided directly by this HTTP API, but is instead performed over ZeroMQ/[rpcq](https://github.com/rigetti/rpcq). Until that changes, we suggest using [pyquil](https://github.com/rigetti/pyquil) to build and execute quantum programs via the Legacy API.  # Legacy API  Our legacy HTTP API remains accessible at https://forest-server.qcs.rigetti.com, and it shares a source of truth with this API's services. You can use either service with the same user account and means of authentication. We strongly recommend using the API documented here, as the legacy API is on the path to deprecation.
19 *
20 * The version of the OpenAPI document: 2020-07-31
21 * Contact: support@rigetti.com
22 * Generated by: https://openapi-generator.tech
23 */
24
25use super::{ContentType, Error, configuration};
26use crate::{apis::ResponseContent, models};
27use ::qcs_api_client_common::backoff::{
28    ExponentialBackoff, duration_from_io_error, duration_from_reqwest_error, duration_from_response,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use qcs_dependencies_client::reqwest::{self, StatusCode};
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "clap")]
36#[allow(unused, reason = "not used in all templates, but required in some")]
37use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
38
39/// Serialize command-line arguments for [`activate_user`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct ActivateUserClapParams {
43    pub activate_user_request: Option<JsonMaybeStdin<crate::models::ActivateUserRequest>>,
44}
45
46#[cfg(feature = "clap")]
47impl ActivateUserClapParams {
48    pub async fn execute(
49        self,
50        configuration: &configuration::Configuration,
51    ) -> Result<models::User, miette::Error> {
52        let request = self
53            .activate_user_request
54            .map(|body| body.into_inner().into_inner());
55
56        activate_user(configuration, request)
57            .await
58            .into_diagnostic()
59    }
60}
61
62/// Serialize command-line arguments for [`add_group_user`]
63#[cfg(feature = "clap")]
64#[derive(Debug, clap::Args)]
65pub struct AddGroupUserClapParams {
66    pub add_group_user_request: JsonMaybeStdin<crate::models::AddGroupUserRequest>,
67}
68
69#[cfg(feature = "clap")]
70impl AddGroupUserClapParams {
71    pub async fn execute(
72        self,
73        configuration: &configuration::Configuration,
74    ) -> Result<(), miette::Error> {
75        let request = self.add_group_user_request.into_inner().into_inner();
76
77        add_group_user(configuration, request)
78            .await
79            .into_diagnostic()
80    }
81}
82
83/// Serialize command-line arguments for [`dismiss_viewer_announcement`]
84#[cfg(feature = "clap")]
85#[derive(Debug, clap::Args)]
86pub struct DismissViewerAnnouncementClapParams {
87    /// The ID of an existing announcement.
88    #[arg(long)]
89    pub announcement_id: i64,
90}
91
92#[cfg(feature = "clap")]
93impl DismissViewerAnnouncementClapParams {
94    pub async fn execute(
95        self,
96        configuration: &configuration::Configuration,
97    ) -> Result<(), miette::Error> {
98        dismiss_viewer_announcement(configuration, self.announcement_id)
99            .await
100            .into_diagnostic()
101    }
102}
103
104/// Serialize command-line arguments for [`get_group_balance`]
105#[cfg(feature = "clap")]
106#[derive(Debug, clap::Args)]
107pub struct GetGroupBalanceClapParams {
108    /// URL encoded name of group for which to retrieve account balance.
109    #[arg(long)]
110    pub group_name: String,
111}
112
113#[cfg(feature = "clap")]
114impl GetGroupBalanceClapParams {
115    pub async fn execute(
116        self,
117        configuration: &configuration::Configuration,
118    ) -> Result<models::AccountBalance, miette::Error> {
119        get_group_balance(configuration, self.group_name.as_str())
120            .await
121            .into_diagnostic()
122    }
123}
124
125/// Serialize command-line arguments for [`get_group_billing_customer`]
126#[cfg(feature = "clap")]
127#[derive(Debug, clap::Args)]
128pub struct GetGroupBillingCustomerClapParams {
129    /// URL-encoded name of group.
130    #[arg(long)]
131    pub group_name: String,
132}
133
134#[cfg(feature = "clap")]
135impl GetGroupBillingCustomerClapParams {
136    pub async fn execute(
137        self,
138        configuration: &configuration::Configuration,
139    ) -> Result<models::BillingCustomer, miette::Error> {
140        get_group_billing_customer(configuration, self.group_name.as_str())
141            .await
142            .into_diagnostic()
143    }
144}
145
146/// Serialize command-line arguments for [`get_group_upcoming_billing_invoice`]
147#[cfg(feature = "clap")]
148#[derive(Debug, clap::Args)]
149pub struct GetGroupUpcomingBillingInvoiceClapParams {
150    /// URL-encoded name of group.
151    #[arg(long)]
152    pub group_name: String,
153}
154
155#[cfg(feature = "clap")]
156impl GetGroupUpcomingBillingInvoiceClapParams {
157    pub async fn execute(
158        self,
159        configuration: &configuration::Configuration,
160    ) -> Result<models::BillingUpcomingInvoice, miette::Error> {
161        get_group_upcoming_billing_invoice(configuration, self.group_name.as_str())
162            .await
163            .into_diagnostic()
164    }
165}
166
167/// Serialize command-line arguments for [`get_user_balance`]
168#[cfg(feature = "clap")]
169#[derive(Debug, clap::Args)]
170pub struct GetUserBalanceClapParams {
171    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
172    #[arg(long)]
173    pub user_id: String,
174}
175
176#[cfg(feature = "clap")]
177impl GetUserBalanceClapParams {
178    pub async fn execute(
179        self,
180        configuration: &configuration::Configuration,
181    ) -> Result<models::AccountBalance, miette::Error> {
182        get_user_balance(configuration, self.user_id.as_str())
183            .await
184            .into_diagnostic()
185    }
186}
187
188/// Serialize command-line arguments for [`get_user_billing_customer`]
189#[cfg(feature = "clap")]
190#[derive(Debug, clap::Args)]
191pub struct GetUserBillingCustomerClapParams {
192    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
193    #[arg(long)]
194    pub user_id: String,
195}
196
197#[cfg(feature = "clap")]
198impl GetUserBillingCustomerClapParams {
199    pub async fn execute(
200        self,
201        configuration: &configuration::Configuration,
202    ) -> Result<models::BillingCustomer, miette::Error> {
203        get_user_billing_customer(configuration, self.user_id.as_str())
204            .await
205            .into_diagnostic()
206    }
207}
208
209/// Serialize command-line arguments for [`get_user_event_billing_price`]
210#[cfg(feature = "clap")]
211#[derive(Debug, clap::Args)]
212pub struct GetUserEventBillingPriceClapParams {
213    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
214    #[arg(long)]
215    pub user_id: String,
216    pub get_account_event_billing_price_request:
217        JsonMaybeStdin<crate::models::GetAccountEventBillingPriceRequest>,
218}
219
220#[cfg(feature = "clap")]
221impl GetUserEventBillingPriceClapParams {
222    pub async fn execute(
223        self,
224        configuration: &configuration::Configuration,
225    ) -> Result<models::EventBillingPriceRate, miette::Error> {
226        let request = self
227            .get_account_event_billing_price_request
228            .into_inner()
229            .into_inner();
230
231        get_user_event_billing_price(configuration, self.user_id.as_str(), request)
232            .await
233            .into_diagnostic()
234    }
235}
236
237/// Serialize command-line arguments for [`get_user_upcoming_billing_invoice`]
238#[cfg(feature = "clap")]
239#[derive(Debug, clap::Args)]
240pub struct GetUserUpcomingBillingInvoiceClapParams {
241    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
242    #[arg(long)]
243    pub user_id: String,
244}
245
246#[cfg(feature = "clap")]
247impl GetUserUpcomingBillingInvoiceClapParams {
248    pub async fn execute(
249        self,
250        configuration: &configuration::Configuration,
251    ) -> Result<models::BillingUpcomingInvoice, miette::Error> {
252        get_user_upcoming_billing_invoice(configuration, self.user_id.as_str())
253            .await
254            .into_diagnostic()
255    }
256}
257
258/// Serialize command-line arguments for [`get_viewer_user_onboarding_completed`]
259#[cfg(feature = "clap")]
260#[derive(Debug, clap::Args)]
261pub struct GetViewerUserOnboardingCompletedClapParams {}
262
263#[cfg(feature = "clap")]
264impl GetViewerUserOnboardingCompletedClapParams {
265    pub async fn execute(
266        self,
267        configuration: &configuration::Configuration,
268    ) -> Result<models::ViewerUserOnboardingCompleted, miette::Error> {
269        get_viewer_user_onboarding_completed(configuration)
270            .await
271            .into_diagnostic()
272    }
273}
274
275/// Serialize command-line arguments for [`list_group_billing_invoice_lines`]
276#[cfg(feature = "clap")]
277#[derive(Debug, clap::Args)]
278pub struct ListGroupBillingInvoiceLinesClapParams {
279    /// URL-encoded name of group.
280    #[arg(long)]
281    pub group_name: String,
282    /// URL-encoded billing invoice id.
283    #[arg(long)]
284    pub billing_invoice_id: String,
285    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
286    #[arg(long)]
287    pub page_token: Option<String>,
288    #[arg(long)]
289    pub page_size: Option<i64>,
290}
291
292#[cfg(feature = "clap")]
293impl ListGroupBillingInvoiceLinesClapParams {
294    pub async fn execute(
295        self,
296        configuration: &configuration::Configuration,
297    ) -> Result<models::ListAccountBillingInvoiceLinesResponse, miette::Error> {
298        list_group_billing_invoice_lines(
299            configuration,
300            self.group_name.as_str(),
301            self.billing_invoice_id.as_str(),
302            self.page_token.as_deref(),
303            self.page_size,
304        )
305        .await
306        .into_diagnostic()
307    }
308}
309
310/// Serialize command-line arguments for [`list_group_billing_invoices`]
311#[cfg(feature = "clap")]
312#[derive(Debug, clap::Args)]
313pub struct ListGroupBillingInvoicesClapParams {
314    /// URL-encoded name of group.
315    #[arg(long)]
316    pub group_name: String,
317    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
318    #[arg(long)]
319    pub page_token: Option<String>,
320    #[arg(long)]
321    pub page_size: Option<i64>,
322}
323
324#[cfg(feature = "clap")]
325impl ListGroupBillingInvoicesClapParams {
326    pub async fn execute(
327        self,
328        configuration: &configuration::Configuration,
329    ) -> Result<models::ListAccountBillingInvoicesResponse, miette::Error> {
330        list_group_billing_invoices(
331            configuration,
332            self.group_name.as_str(),
333            self.page_token.as_deref(),
334            self.page_size,
335        )
336        .await
337        .into_diagnostic()
338    }
339}
340
341/// Serialize command-line arguments for [`list_group_upcoming_billing_invoice_lines`]
342#[cfg(feature = "clap")]
343#[derive(Debug, clap::Args)]
344pub struct ListGroupUpcomingBillingInvoiceLinesClapParams {
345    /// URL-encoded name of group.
346    #[arg(long)]
347    pub group_name: String,
348    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
349    #[arg(long)]
350    pub page_token: Option<String>,
351    #[arg(long)]
352    pub page_size: Option<i64>,
353}
354
355#[cfg(feature = "clap")]
356impl ListGroupUpcomingBillingInvoiceLinesClapParams {
357    pub async fn execute(
358        self,
359        configuration: &configuration::Configuration,
360    ) -> Result<models::ListAccountBillingInvoiceLinesResponse, miette::Error> {
361        list_group_upcoming_billing_invoice_lines(
362            configuration,
363            self.group_name.as_str(),
364            self.page_token.as_deref(),
365            self.page_size,
366        )
367        .await
368        .into_diagnostic()
369    }
370}
371
372/// Serialize command-line arguments for [`list_group_users`]
373#[cfg(feature = "clap")]
374#[derive(Debug, clap::Args)]
375pub struct ListGroupUsersClapParams {
376    /// URL encoded name of group for which to retrieve users.
377    #[arg(long)]
378    pub group_name: String,
379    #[arg(long)]
380    pub page_size: Option<i64>,
381    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
382    #[arg(long)]
383    pub page_token: Option<String>,
384}
385
386#[cfg(feature = "clap")]
387impl ListGroupUsersClapParams {
388    pub async fn execute(
389        self,
390        configuration: &configuration::Configuration,
391    ) -> Result<models::ListGroupUsersResponse, miette::Error> {
392        list_group_users(
393            configuration,
394            self.group_name.as_str(),
395            self.page_size,
396            self.page_token.as_deref(),
397        )
398        .await
399        .into_diagnostic()
400    }
401}
402
403/// Serialize command-line arguments for [`list_user_billing_invoice_lines`]
404#[cfg(feature = "clap")]
405#[derive(Debug, clap::Args)]
406pub struct ListUserBillingInvoiceLinesClapParams {
407    /// URL-encoded QCS id of user. May be found as `idpId` in the `AuthGetUser` API call.
408    #[arg(long)]
409    pub user_id: String,
410    /// URL-encoded billing invoice id.
411    #[arg(long)]
412    pub billing_invoice_id: String,
413    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
414    #[arg(long)]
415    pub page_token: Option<String>,
416    #[arg(long)]
417    pub page_size: Option<i64>,
418}
419
420#[cfg(feature = "clap")]
421impl ListUserBillingInvoiceLinesClapParams {
422    pub async fn execute(
423        self,
424        configuration: &configuration::Configuration,
425    ) -> Result<models::ListAccountBillingInvoiceLinesResponse, miette::Error> {
426        list_user_billing_invoice_lines(
427            configuration,
428            self.user_id.as_str(),
429            self.billing_invoice_id.as_str(),
430            self.page_token.as_deref(),
431            self.page_size,
432        )
433        .await
434        .into_diagnostic()
435    }
436}
437
438/// Serialize command-line arguments for [`list_user_billing_invoices`]
439#[cfg(feature = "clap")]
440#[derive(Debug, clap::Args)]
441pub struct ListUserBillingInvoicesClapParams {
442    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
443    #[arg(long)]
444    pub user_id: String,
445    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
446    #[arg(long)]
447    pub page_token: Option<String>,
448    #[arg(long)]
449    pub page_size: Option<i64>,
450}
451
452#[cfg(feature = "clap")]
453impl ListUserBillingInvoicesClapParams {
454    pub async fn execute(
455        self,
456        configuration: &configuration::Configuration,
457    ) -> Result<models::ListAccountBillingInvoicesResponse, miette::Error> {
458        list_user_billing_invoices(
459            configuration,
460            self.user_id.as_str(),
461            self.page_token.as_deref(),
462            self.page_size,
463        )
464        .await
465        .into_diagnostic()
466    }
467}
468
469/// Serialize command-line arguments for [`list_user_groups`]
470#[cfg(feature = "clap")]
471#[derive(Debug, clap::Args)]
472pub struct ListUserGroupsClapParams {
473    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
474    #[arg(long)]
475    pub user_id: String,
476    #[arg(long)]
477    pub page_size: Option<i64>,
478    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
479    #[arg(long)]
480    pub page_token: Option<String>,
481}
482
483#[cfg(feature = "clap")]
484impl ListUserGroupsClapParams {
485    pub async fn execute(
486        self,
487        configuration: &configuration::Configuration,
488    ) -> Result<models::ListGroupsResponse, miette::Error> {
489        list_user_groups(
490            configuration,
491            self.user_id.as_str(),
492            self.page_size,
493            self.page_token.as_deref(),
494        )
495        .await
496        .into_diagnostic()
497    }
498}
499
500/// Serialize command-line arguments for [`list_user_upcoming_billing_invoice_lines`]
501#[cfg(feature = "clap")]
502#[derive(Debug, clap::Args)]
503pub struct ListUserUpcomingBillingInvoiceLinesClapParams {
504    /// The user's QCS id. May be found as `idpId` in the `AuthGetUser` API call.
505    #[arg(long)]
506    pub user_id: String,
507    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
508    #[arg(long)]
509    pub page_token: Option<String>,
510    #[arg(long)]
511    pub page_size: Option<i64>,
512}
513
514#[cfg(feature = "clap")]
515impl ListUserUpcomingBillingInvoiceLinesClapParams {
516    pub async fn execute(
517        self,
518        configuration: &configuration::Configuration,
519    ) -> Result<models::ListAccountBillingInvoiceLinesResponse, miette::Error> {
520        list_user_upcoming_billing_invoice_lines(
521            configuration,
522            self.user_id.as_str(),
523            self.page_token.as_deref(),
524            self.page_size,
525        )
526        .await
527        .into_diagnostic()
528    }
529}
530
531/// Serialize command-line arguments for [`list_viewer_announcements`]
532#[cfg(feature = "clap")]
533#[derive(Debug, clap::Args)]
534pub struct ListViewerAnnouncementsClapParams {
535    #[arg(long)]
536    pub page_size: Option<i64>,
537    /// An opaque token that can be appended to a request query to retrieve the next page of results. Empty if there are no more results to retrieve.
538    #[arg(long)]
539    pub page_token: Option<String>,
540    /// Include dismissed announcements in the response.
541    #[arg(long)]
542    pub include_dismissed: Option<bool>,
543}
544
545#[cfg(feature = "clap")]
546impl ListViewerAnnouncementsClapParams {
547    pub async fn execute(
548        self,
549        configuration: &configuration::Configuration,
550    ) -> Result<models::AnnouncementsResponse, miette::Error> {
551        list_viewer_announcements(
552            configuration,
553            self.page_size,
554            self.page_token.as_deref(),
555            self.include_dismissed,
556        )
557        .await
558        .into_diagnostic()
559    }
560}
561
562/// Serialize command-line arguments for [`put_viewer_user_onboarding_completed`]
563#[cfg(feature = "clap")]
564#[derive(Debug, clap::Args)]
565pub struct PutViewerUserOnboardingCompletedClapParams {
566    pub viewer_user_onboarding_completed:
567        Option<JsonMaybeStdin<crate::models::ViewerUserOnboardingCompleted>>,
568}
569
570#[cfg(feature = "clap")]
571impl PutViewerUserOnboardingCompletedClapParams {
572    pub async fn execute(
573        self,
574        configuration: &configuration::Configuration,
575    ) -> Result<models::ViewerUserOnboardingCompleted, miette::Error> {
576        let request = self
577            .viewer_user_onboarding_completed
578            .map(|body| body.into_inner().into_inner());
579
580        put_viewer_user_onboarding_completed(configuration, request)
581            .await
582            .into_diagnostic()
583    }
584}
585
586/// Serialize command-line arguments for [`remove_group_user`]
587#[cfg(feature = "clap")]
588#[derive(Debug, clap::Args)]
589pub struct RemoveGroupUserClapParams {
590    pub remove_group_user_request: JsonMaybeStdin<crate::models::RemoveGroupUserRequest>,
591}
592
593#[cfg(feature = "clap")]
594impl RemoveGroupUserClapParams {
595    pub async fn execute(
596        self,
597        configuration: &configuration::Configuration,
598    ) -> Result<(), miette::Error> {
599        let request = self.remove_group_user_request.into_inner().into_inner();
600
601        remove_group_user(configuration, request)
602            .await
603            .into_diagnostic()
604    }
605}
606
607/// Serialize command-line arguments for [`update_viewer_user_profile`]
608#[cfg(feature = "clap")]
609#[derive(Debug, clap::Args)]
610pub struct UpdateViewerUserProfileClapParams {
611    pub update_viewer_user_profile_request:
612        JsonMaybeStdin<crate::models::UpdateViewerUserProfileRequest>,
613}
614
615#[cfg(feature = "clap")]
616impl UpdateViewerUserProfileClapParams {
617    pub async fn execute(
618        self,
619        configuration: &configuration::Configuration,
620    ) -> Result<models::User, miette::Error> {
621        let request = self
622            .update_viewer_user_profile_request
623            .into_inner()
624            .into_inner();
625
626        update_viewer_user_profile(configuration, request)
627            .await
628            .into_diagnostic()
629    }
630}
631
632/// struct for typed errors of method [`activate_user`]
633#[derive(Debug, Clone, Serialize, Deserialize)]
634#[serde(untagged)]
635pub enum ActivateUserError {
636    Status422(models::Error),
637    UnknownValue(serde_json::Value),
638}
639
640/// struct for typed errors of method [`add_group_user`]
641#[derive(Debug, Clone, Serialize, Deserialize)]
642#[serde(untagged)]
643pub enum AddGroupUserError {
644    Status404(models::Error),
645    Status422(models::Error),
646    UnknownValue(serde_json::Value),
647}
648
649/// struct for typed errors of method [`dismiss_viewer_announcement`]
650#[derive(Debug, Clone, Serialize, Deserialize)]
651#[serde(untagged)]
652pub enum DismissViewerAnnouncementError {
653    Status401(models::Error),
654    Status404(models::Error),
655    UnknownValue(serde_json::Value),
656}
657
658/// struct for typed errors of method [`get_group_balance`]
659#[derive(Debug, Clone, Serialize, Deserialize)]
660#[serde(untagged)]
661pub enum GetGroupBalanceError {
662    Status403(models::Error),
663    Status404(models::Error),
664    Status422(models::Error),
665    UnknownValue(serde_json::Value),
666}
667
668/// struct for typed errors of method [`get_group_billing_customer`]
669#[derive(Debug, Clone, Serialize, Deserialize)]
670#[serde(untagged)]
671pub enum GetGroupBillingCustomerError {
672    Status403(models::Error),
673    Status404(models::Error),
674    UnknownValue(serde_json::Value),
675}
676
677/// struct for typed errors of method [`get_group_upcoming_billing_invoice`]
678#[derive(Debug, Clone, Serialize, Deserialize)]
679#[serde(untagged)]
680pub enum GetGroupUpcomingBillingInvoiceError {
681    Status403(models::Error),
682    Status404(models::Error),
683    UnknownValue(serde_json::Value),
684}
685
686/// struct for typed errors of method [`get_user_balance`]
687#[derive(Debug, Clone, Serialize, Deserialize)]
688#[serde(untagged)]
689pub enum GetUserBalanceError {
690    Status403(models::Error),
691    Status404(models::Error),
692    Status422(models::Error),
693    UnknownValue(serde_json::Value),
694}
695
696/// struct for typed errors of method [`get_user_billing_customer`]
697#[derive(Debug, Clone, Serialize, Deserialize)]
698#[serde(untagged)]
699pub enum GetUserBillingCustomerError {
700    Status403(models::Error),
701    Status404(models::Error),
702    UnknownValue(serde_json::Value),
703}
704
705/// struct for typed errors of method [`get_user_event_billing_price`]
706#[derive(Debug, Clone, Serialize, Deserialize)]
707#[serde(untagged)]
708pub enum GetUserEventBillingPriceError {
709    Status403(models::Error),
710    Status404(models::Error),
711    Status422(models::Error),
712    UnknownValue(serde_json::Value),
713}
714
715/// struct for typed errors of method [`get_user_upcoming_billing_invoice`]
716#[derive(Debug, Clone, Serialize, Deserialize)]
717#[serde(untagged)]
718pub enum GetUserUpcomingBillingInvoiceError {
719    Status403(models::Error),
720    Status404(models::Error),
721    UnknownValue(serde_json::Value),
722}
723
724/// struct for typed errors of method [`get_viewer_user_onboarding_completed`]
725#[derive(Debug, Clone, Serialize, Deserialize)]
726#[serde(untagged)]
727pub enum GetViewerUserOnboardingCompletedError {
728    Status401(models::Error),
729    UnknownValue(serde_json::Value),
730}
731
732/// struct for typed errors of method [`list_group_billing_invoice_lines`]
733#[derive(Debug, Clone, Serialize, Deserialize)]
734#[serde(untagged)]
735pub enum ListGroupBillingInvoiceLinesError {
736    Status403(models::Error),
737    Status404(models::Error),
738    UnknownValue(serde_json::Value),
739}
740
741/// struct for typed errors of method [`list_group_billing_invoices`]
742#[derive(Debug, Clone, Serialize, Deserialize)]
743#[serde(untagged)]
744pub enum ListGroupBillingInvoicesError {
745    Status403(models::Error),
746    Status404(models::Error),
747    UnknownValue(serde_json::Value),
748}
749
750/// struct for typed errors of method [`list_group_upcoming_billing_invoice_lines`]
751#[derive(Debug, Clone, Serialize, Deserialize)]
752#[serde(untagged)]
753pub enum ListGroupUpcomingBillingInvoiceLinesError {
754    Status403(models::Error),
755    Status404(models::Error),
756    UnknownValue(serde_json::Value),
757}
758
759/// struct for typed errors of method [`list_group_users`]
760#[derive(Debug, Clone, Serialize, Deserialize)]
761#[serde(untagged)]
762pub enum ListGroupUsersError {
763    Status404(models::Error),
764    Status422(models::Error),
765    UnknownValue(serde_json::Value),
766}
767
768/// struct for typed errors of method [`list_user_billing_invoice_lines`]
769#[derive(Debug, Clone, Serialize, Deserialize)]
770#[serde(untagged)]
771pub enum ListUserBillingInvoiceLinesError {
772    Status403(models::Error),
773    Status404(models::Error),
774    UnknownValue(serde_json::Value),
775}
776
777/// struct for typed errors of method [`list_user_billing_invoices`]
778#[derive(Debug, Clone, Serialize, Deserialize)]
779#[serde(untagged)]
780pub enum ListUserBillingInvoicesError {
781    Status403(models::Error),
782    Status404(models::Error),
783    UnknownValue(serde_json::Value),
784}
785
786/// struct for typed errors of method [`list_user_groups`]
787#[derive(Debug, Clone, Serialize, Deserialize)]
788#[serde(untagged)]
789pub enum ListUserGroupsError {
790    Status422(models::Error),
791    UnknownValue(serde_json::Value),
792}
793
794/// struct for typed errors of method [`list_user_upcoming_billing_invoice_lines`]
795#[derive(Debug, Clone, Serialize, Deserialize)]
796#[serde(untagged)]
797pub enum ListUserUpcomingBillingInvoiceLinesError {
798    Status403(models::Error),
799    Status404(models::Error),
800    UnknownValue(serde_json::Value),
801}
802
803/// struct for typed errors of method [`list_viewer_announcements`]
804#[derive(Debug, Clone, Serialize, Deserialize)]
805#[serde(untagged)]
806pub enum ListViewerAnnouncementsError {
807    Status401(models::Error),
808    Status422(models::Error),
809    UnknownValue(serde_json::Value),
810}
811
812/// struct for typed errors of method [`put_viewer_user_onboarding_completed`]
813#[derive(Debug, Clone, Serialize, Deserialize)]
814#[serde(untagged)]
815pub enum PutViewerUserOnboardingCompletedError {
816    Status401(models::Error),
817    UnknownValue(serde_json::Value),
818}
819
820/// struct for typed errors of method [`remove_group_user`]
821#[derive(Debug, Clone, Serialize, Deserialize)]
822#[serde(untagged)]
823pub enum RemoveGroupUserError {
824    Status404(models::Error),
825    Status422(models::Error),
826    UnknownValue(serde_json::Value),
827}
828
829/// struct for typed errors of method [`update_viewer_user_profile`]
830#[derive(Debug, Clone, Serialize, Deserialize)]
831#[serde(untagged)]
832pub enum UpdateViewerUserProfileError {
833    Status401(models::Error),
834    Status404(models::Error),
835    Status422(models::Error),
836    UnknownValue(serde_json::Value),
837}
838
839async fn activate_user_inner(
840    configuration: &configuration::Configuration,
841    backoff: &mut ExponentialBackoff,
842    activate_user_request: Option<crate::models::ActivateUserRequest>,
843) -> Result<models::User, Error<ActivateUserError>> {
844    let local_var_configuration = configuration;
845    // add a prefix to parameters to efficiently prevent name collisions
846    let p_body_activate_user_request = activate_user_request;
847
848    let local_var_client = &local_var_configuration.client;
849
850    let local_var_uri_str = format!(
851        "{}/v1/users:activate",
852        local_var_configuration.qcs_config.api_url()
853    );
854    let mut local_var_req_builder =
855        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
856
857    #[cfg(feature = "tracing")]
858    {
859        // Ignore parsing errors if the URL is invalid for some reason.
860        // If it is invalid, it will turn up as an error later when actually making the request.
861        let local_var_do_tracing = local_var_uri_str
862            .parse::<::url::Url>()
863            .ok()
864            .is_none_or(|url| {
865                configuration
866                    .qcs_config
867                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
868            });
869
870        if local_var_do_tracing {
871            ::tracing::debug!(
872                url=%local_var_uri_str,
873                method="POST",
874                "making activate_user request",
875            );
876        }
877    }
878
879    // Use the QCS Bearer token if a client OAuthSession is present,
880    // but do not require one when the security schema says it is optional.
881    {
882        use qcs_api_client_common::configuration::TokenError;
883
884        #[allow(
885            clippy::nonminimal_bool,
886            clippy::eq_op,
887            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
888        )]
889        let is_jwt_bearer_optional: bool = false;
890
891        let token = local_var_configuration
892            .qcs_config
893            .get_bearer_access_token()
894            .await;
895
896        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
897            // the client is configured without any OAuthSession, but this call does not require one.
898            #[cfg(feature = "tracing")]
899            tracing::debug!(
900                "No client credentials found, but this call does not require authentication."
901            );
902        } else {
903            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
904        }
905    }
906
907    local_var_req_builder = local_var_req_builder.json(&p_body_activate_user_request);
908
909    let local_var_req = local_var_req_builder.build()?;
910    let local_var_resp = local_var_client.execute(local_var_req).await?;
911
912    let local_var_status = local_var_resp.status();
913    let local_var_raw_content_type = local_var_resp
914        .headers()
915        .get("content-type")
916        .and_then(|v| v.to_str().ok())
917        .unwrap_or("application/octet-stream")
918        .to_string();
919    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
920
921    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
922        let local_var_content = local_var_resp.text().await?;
923        match local_var_content_type {
924            ContentType::Json => serde_path_to_error::deserialize(
925                &mut serde_json::Deserializer::from_str(&local_var_content),
926            )
927            .map_err(Error::from),
928            ContentType::Text => Err(Error::InvalidContentType {
929                content_type: local_var_raw_content_type,
930                return_type: "models::User",
931            }),
932            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
933                content_type: unknown_type,
934                return_type: "models::User",
935            }),
936        }
937    } else {
938        let local_var_retry_delay =
939            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
940        let local_var_content = local_var_resp.text().await?;
941        let local_var_entity: Option<ActivateUserError> =
942            serde_json::from_str(&local_var_content).ok();
943        let local_var_error = ResponseContent {
944            status: local_var_status,
945            content: local_var_content,
946            entity: local_var_entity,
947            retry_delay: local_var_retry_delay,
948        };
949        Err(Error::ResponseError(local_var_error))
950    }
951}
952
953/// Activate a user, completing an invitation request.
954pub async fn activate_user(
955    configuration: &configuration::Configuration,
956    activate_user_request: Option<crate::models::ActivateUserRequest>,
957) -> Result<models::User, Error<ActivateUserError>> {
958    let mut backoff = configuration.backoff.clone();
959    let mut refreshed_credentials = false;
960    let method = reqwest::Method::POST;
961    loop {
962        let result =
963            activate_user_inner(configuration, &mut backoff, activate_user_request.clone()).await;
964
965        match result {
966            Ok(result) => return Ok(result),
967            Err(Error::ResponseError(response)) => {
968                if !refreshed_credentials
969                    && matches!(
970                        response.status,
971                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
972                    )
973                {
974                    // Attempt to refresh credentials
975                    match configuration.qcs_config.refresh().await {
976                        Ok(_) => {
977                            refreshed_credentials = true;
978                            continue;
979                        }
980                        Err(::qcs_api_client_common::configuration::TokenError::Write {
981                            error,
982                            oauth_session: _,
983                        }) => {
984                            // Token refresh succeeded but persistence failed
985                            // The token is already in memory and will be used for this request
986                            #[cfg(feature = "tracing")]
987                            tracing::warn!(
988                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
989                                error
990                            );
991                            refreshed_credentials = true;
992                            continue;
993                        }
994                        Err(e) => return Err(e.into()),
995                    }
996                } else if let Some(duration) = response.retry_delay {
997                    tokio::time::sleep(duration).await;
998                    continue;
999                }
1000
1001                return Err(Error::ResponseError(response));
1002            }
1003            Err(Error::Reqwest(error)) => {
1004                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1005                    tokio::time::sleep(duration).await;
1006                    continue;
1007                }
1008
1009                return Err(Error::Reqwest(error));
1010            }
1011            Err(Error::Io(error)) => {
1012                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1013                    tokio::time::sleep(duration).await;
1014                    continue;
1015                }
1016
1017                return Err(Error::Io(error));
1018            }
1019            Err(error) => return Err(error),
1020        }
1021    }
1022}
1023async fn add_group_user_inner(
1024    configuration: &configuration::Configuration,
1025    backoff: &mut ExponentialBackoff,
1026    add_group_user_request: crate::models::AddGroupUserRequest,
1027) -> Result<(), Error<AddGroupUserError>> {
1028    let local_var_configuration = configuration;
1029    // add a prefix to parameters to efficiently prevent name collisions
1030    let p_body_add_group_user_request = add_group_user_request;
1031
1032    let local_var_client = &local_var_configuration.client;
1033
1034    let local_var_uri_str = format!(
1035        "{}/v1/groups:addUser",
1036        local_var_configuration.qcs_config.api_url()
1037    );
1038    let mut local_var_req_builder =
1039        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
1040
1041    #[cfg(feature = "tracing")]
1042    {
1043        // Ignore parsing errors if the URL is invalid for some reason.
1044        // If it is invalid, it will turn up as an error later when actually making the request.
1045        let local_var_do_tracing = local_var_uri_str
1046            .parse::<::url::Url>()
1047            .ok()
1048            .is_none_or(|url| {
1049                configuration
1050                    .qcs_config
1051                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1052            });
1053
1054        if local_var_do_tracing {
1055            ::tracing::debug!(
1056                url=%local_var_uri_str,
1057                method="POST",
1058                "making add_group_user request",
1059            );
1060        }
1061    }
1062
1063    // Use the QCS Bearer token if a client OAuthSession is present,
1064    // but do not require one when the security schema says it is optional.
1065    {
1066        use qcs_api_client_common::configuration::TokenError;
1067
1068        #[allow(
1069            clippy::nonminimal_bool,
1070            clippy::eq_op,
1071            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1072        )]
1073        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1074
1075        let token = local_var_configuration
1076            .qcs_config
1077            .get_bearer_access_token()
1078            .await;
1079
1080        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1081            // the client is configured without any OAuthSession, but this call does not require one.
1082            #[cfg(feature = "tracing")]
1083            tracing::debug!(
1084                "No client credentials found, but this call does not require authentication."
1085            );
1086        } else {
1087            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1088        }
1089    }
1090
1091    local_var_req_builder = local_var_req_builder.json(&p_body_add_group_user_request);
1092
1093    let local_var_req = local_var_req_builder.build()?;
1094    let local_var_resp = local_var_client.execute(local_var_req).await?;
1095
1096    let local_var_status = local_var_resp.status();
1097
1098    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1099        Ok(())
1100    } else {
1101        let local_var_retry_delay =
1102            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1103        let local_var_content = local_var_resp.text().await?;
1104        let local_var_entity: Option<AddGroupUserError> =
1105            serde_json::from_str(&local_var_content).ok();
1106        let local_var_error = ResponseContent {
1107            status: local_var_status,
1108            content: local_var_content,
1109            entity: local_var_entity,
1110            retry_delay: local_var_retry_delay,
1111        };
1112        Err(Error::ResponseError(local_var_error))
1113    }
1114}
1115
1116/// Add a user to a group. Note, group membership may take several minutes to update within our identity provider. After adding a user to a group, please allow up to 60 minutes for changes to be reflected.
1117pub async fn add_group_user(
1118    configuration: &configuration::Configuration,
1119    add_group_user_request: crate::models::AddGroupUserRequest,
1120) -> Result<(), Error<AddGroupUserError>> {
1121    let mut backoff = configuration.backoff.clone();
1122    let mut refreshed_credentials = false;
1123    let method = reqwest::Method::POST;
1124    loop {
1125        let result =
1126            add_group_user_inner(configuration, &mut backoff, add_group_user_request.clone()).await;
1127
1128        match result {
1129            Ok(result) => return Ok(result),
1130            Err(Error::ResponseError(response)) => {
1131                if !refreshed_credentials
1132                    && matches!(
1133                        response.status,
1134                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1135                    )
1136                {
1137                    // Attempt to refresh credentials
1138                    match configuration.qcs_config.refresh().await {
1139                        Ok(_) => {
1140                            refreshed_credentials = true;
1141                            continue;
1142                        }
1143                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1144                            error,
1145                            oauth_session: _,
1146                        }) => {
1147                            // Token refresh succeeded but persistence failed
1148                            // The token is already in memory and will be used for this request
1149                            #[cfg(feature = "tracing")]
1150                            tracing::warn!(
1151                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1152                                error
1153                            );
1154                            refreshed_credentials = true;
1155                            continue;
1156                        }
1157                        Err(e) => return Err(e.into()),
1158                    }
1159                } else if let Some(duration) = response.retry_delay {
1160                    tokio::time::sleep(duration).await;
1161                    continue;
1162                }
1163
1164                return Err(Error::ResponseError(response));
1165            }
1166            Err(Error::Reqwest(error)) => {
1167                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1168                    tokio::time::sleep(duration).await;
1169                    continue;
1170                }
1171
1172                return Err(Error::Reqwest(error));
1173            }
1174            Err(Error::Io(error)) => {
1175                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1176                    tokio::time::sleep(duration).await;
1177                    continue;
1178                }
1179
1180                return Err(Error::Io(error));
1181            }
1182            Err(error) => return Err(error),
1183        }
1184    }
1185}
1186async fn dismiss_viewer_announcement_inner(
1187    configuration: &configuration::Configuration,
1188    backoff: &mut ExponentialBackoff,
1189    announcement_id: i64,
1190) -> Result<(), Error<DismissViewerAnnouncementError>> {
1191    let local_var_configuration = configuration;
1192    // add a prefix to parameters to efficiently prevent name collisions
1193    let p_path_announcement_id = announcement_id;
1194
1195    let local_var_client = &local_var_configuration.client;
1196
1197    let local_var_uri_str = format!(
1198        "{}/v1/viewer/announcements/{announcementId}",
1199        local_var_configuration.qcs_config.api_url(),
1200        announcementId = p_path_announcement_id
1201    );
1202    let mut local_var_req_builder =
1203        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
1204
1205    #[cfg(feature = "tracing")]
1206    {
1207        // Ignore parsing errors if the URL is invalid for some reason.
1208        // If it is invalid, it will turn up as an error later when actually making the request.
1209        let local_var_do_tracing = local_var_uri_str
1210            .parse::<::url::Url>()
1211            .ok()
1212            .is_none_or(|url| {
1213                configuration
1214                    .qcs_config
1215                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1216            });
1217
1218        if local_var_do_tracing {
1219            ::tracing::debug!(
1220                url=%local_var_uri_str,
1221                method="DELETE",
1222                "making dismiss_viewer_announcement request",
1223            );
1224        }
1225    }
1226
1227    // Use the QCS Bearer token if a client OAuthSession is present,
1228    // but do not require one when the security schema says it is optional.
1229    {
1230        use qcs_api_client_common::configuration::TokenError;
1231
1232        #[allow(
1233            clippy::nonminimal_bool,
1234            clippy::eq_op,
1235            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1236        )]
1237        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1238
1239        let token = local_var_configuration
1240            .qcs_config
1241            .get_bearer_access_token()
1242            .await;
1243
1244        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1245            // the client is configured without any OAuthSession, but this call does not require one.
1246            #[cfg(feature = "tracing")]
1247            tracing::debug!(
1248                "No client credentials found, but this call does not require authentication."
1249            );
1250        } else {
1251            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1252        }
1253    }
1254
1255    let local_var_req = local_var_req_builder.build()?;
1256    let local_var_resp = local_var_client.execute(local_var_req).await?;
1257
1258    let local_var_status = local_var_resp.status();
1259
1260    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1261        Ok(())
1262    } else {
1263        let local_var_retry_delay =
1264            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1265        let local_var_content = local_var_resp.text().await?;
1266        let local_var_entity: Option<DismissViewerAnnouncementError> =
1267            serde_json::from_str(&local_var_content).ok();
1268        let local_var_error = ResponseContent {
1269            status: local_var_status,
1270            content: local_var_content,
1271            entity: local_var_entity,
1272            retry_delay: local_var_retry_delay,
1273        };
1274        Err(Error::ResponseError(local_var_error))
1275    }
1276}
1277
1278/// Dismiss an announcement for an authenticating user, indicating that they do not want to see it again.
1279pub async fn dismiss_viewer_announcement(
1280    configuration: &configuration::Configuration,
1281    announcement_id: i64,
1282) -> Result<(), Error<DismissViewerAnnouncementError>> {
1283    let mut backoff = configuration.backoff.clone();
1284    let mut refreshed_credentials = false;
1285    let method = reqwest::Method::DELETE;
1286    loop {
1287        let result =
1288            dismiss_viewer_announcement_inner(configuration, &mut backoff, announcement_id.clone())
1289                .await;
1290
1291        match result {
1292            Ok(result) => return Ok(result),
1293            Err(Error::ResponseError(response)) => {
1294                if !refreshed_credentials
1295                    && matches!(
1296                        response.status,
1297                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1298                    )
1299                {
1300                    // Attempt to refresh credentials
1301                    match configuration.qcs_config.refresh().await {
1302                        Ok(_) => {
1303                            refreshed_credentials = true;
1304                            continue;
1305                        }
1306                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1307                            error,
1308                            oauth_session: _,
1309                        }) => {
1310                            // Token refresh succeeded but persistence failed
1311                            // The token is already in memory and will be used for this request
1312                            #[cfg(feature = "tracing")]
1313                            tracing::warn!(
1314                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1315                                error
1316                            );
1317                            refreshed_credentials = true;
1318                            continue;
1319                        }
1320                        Err(e) => return Err(e.into()),
1321                    }
1322                } else if let Some(duration) = response.retry_delay {
1323                    tokio::time::sleep(duration).await;
1324                    continue;
1325                }
1326
1327                return Err(Error::ResponseError(response));
1328            }
1329            Err(Error::Reqwest(error)) => {
1330                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1331                    tokio::time::sleep(duration).await;
1332                    continue;
1333                }
1334
1335                return Err(Error::Reqwest(error));
1336            }
1337            Err(Error::Io(error)) => {
1338                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1339                    tokio::time::sleep(duration).await;
1340                    continue;
1341                }
1342
1343                return Err(Error::Io(error));
1344            }
1345            Err(error) => return Err(error),
1346        }
1347    }
1348}
1349async fn get_group_balance_inner(
1350    configuration: &configuration::Configuration,
1351    backoff: &mut ExponentialBackoff,
1352    group_name: &str,
1353) -> Result<models::AccountBalance, Error<GetGroupBalanceError>> {
1354    let local_var_configuration = configuration;
1355    // add a prefix to parameters to efficiently prevent name collisions
1356    let p_path_group_name = group_name;
1357
1358    let local_var_client = &local_var_configuration.client;
1359
1360    let local_var_uri_str = format!(
1361        "{}/v1/groups/{groupName}/balance",
1362        local_var_configuration.qcs_config.api_url(),
1363        groupName = crate::apis::urlencode(p_path_group_name)
1364    );
1365    let mut local_var_req_builder =
1366        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
1367
1368    #[cfg(feature = "tracing")]
1369    {
1370        // Ignore parsing errors if the URL is invalid for some reason.
1371        // If it is invalid, it will turn up as an error later when actually making the request.
1372        let local_var_do_tracing = local_var_uri_str
1373            .parse::<::url::Url>()
1374            .ok()
1375            .is_none_or(|url| {
1376                configuration
1377                    .qcs_config
1378                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1379            });
1380
1381        if local_var_do_tracing {
1382            ::tracing::debug!(
1383                url=%local_var_uri_str,
1384                method="GET",
1385                "making get_group_balance request",
1386            );
1387        }
1388    }
1389
1390    // Use the QCS Bearer token if a client OAuthSession is present,
1391    // but do not require one when the security schema says it is optional.
1392    {
1393        use qcs_api_client_common::configuration::TokenError;
1394
1395        #[allow(
1396            clippy::nonminimal_bool,
1397            clippy::eq_op,
1398            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1399        )]
1400        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1401
1402        let token = local_var_configuration
1403            .qcs_config
1404            .get_bearer_access_token()
1405            .await;
1406
1407        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1408            // the client is configured without any OAuthSession, but this call does not require one.
1409            #[cfg(feature = "tracing")]
1410            tracing::debug!(
1411                "No client credentials found, but this call does not require authentication."
1412            );
1413        } else {
1414            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1415        }
1416    }
1417
1418    let local_var_req = local_var_req_builder.build()?;
1419    let local_var_resp = local_var_client.execute(local_var_req).await?;
1420
1421    let local_var_status = local_var_resp.status();
1422    let local_var_raw_content_type = local_var_resp
1423        .headers()
1424        .get("content-type")
1425        .and_then(|v| v.to_str().ok())
1426        .unwrap_or("application/octet-stream")
1427        .to_string();
1428    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1429
1430    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1431        let local_var_content = local_var_resp.text().await?;
1432        match local_var_content_type {
1433            ContentType::Json => serde_path_to_error::deserialize(
1434                &mut serde_json::Deserializer::from_str(&local_var_content),
1435            )
1436            .map_err(Error::from),
1437            ContentType::Text => Err(Error::InvalidContentType {
1438                content_type: local_var_raw_content_type,
1439                return_type: "models::AccountBalance",
1440            }),
1441            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1442                content_type: unknown_type,
1443                return_type: "models::AccountBalance",
1444            }),
1445        }
1446    } else {
1447        let local_var_retry_delay =
1448            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1449        let local_var_content = local_var_resp.text().await?;
1450        let local_var_entity: Option<GetGroupBalanceError> =
1451            serde_json::from_str(&local_var_content).ok();
1452        let local_var_error = ResponseContent {
1453            status: local_var_status,
1454            content: local_var_content,
1455            entity: local_var_entity,
1456            retry_delay: local_var_retry_delay,
1457        };
1458        Err(Error::ResponseError(local_var_error))
1459    }
1460}
1461
1462/// Retrieve the balance of the requested QCS group account.
1463pub async fn get_group_balance(
1464    configuration: &configuration::Configuration,
1465    group_name: &str,
1466) -> Result<models::AccountBalance, Error<GetGroupBalanceError>> {
1467    let mut backoff = configuration.backoff.clone();
1468    let mut refreshed_credentials = false;
1469    let method = reqwest::Method::GET;
1470    loop {
1471        let result = get_group_balance_inner(configuration, &mut backoff, group_name.clone()).await;
1472
1473        match result {
1474            Ok(result) => return Ok(result),
1475            Err(Error::ResponseError(response)) => {
1476                if !refreshed_credentials
1477                    && matches!(
1478                        response.status,
1479                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1480                    )
1481                {
1482                    // Attempt to refresh credentials
1483                    match configuration.qcs_config.refresh().await {
1484                        Ok(_) => {
1485                            refreshed_credentials = true;
1486                            continue;
1487                        }
1488                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1489                            error,
1490                            oauth_session: _,
1491                        }) => {
1492                            // Token refresh succeeded but persistence failed
1493                            // The token is already in memory and will be used for this request
1494                            #[cfg(feature = "tracing")]
1495                            tracing::warn!(
1496                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1497                                error
1498                            );
1499                            refreshed_credentials = true;
1500                            continue;
1501                        }
1502                        Err(e) => return Err(e.into()),
1503                    }
1504                } else if let Some(duration) = response.retry_delay {
1505                    tokio::time::sleep(duration).await;
1506                    continue;
1507                }
1508
1509                return Err(Error::ResponseError(response));
1510            }
1511            Err(Error::Reqwest(error)) => {
1512                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1513                    tokio::time::sleep(duration).await;
1514                    continue;
1515                }
1516
1517                return Err(Error::Reqwest(error));
1518            }
1519            Err(Error::Io(error)) => {
1520                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1521                    tokio::time::sleep(duration).await;
1522                    continue;
1523                }
1524
1525                return Err(Error::Io(error));
1526            }
1527            Err(error) => return Err(error),
1528        }
1529    }
1530}
1531async fn get_group_billing_customer_inner(
1532    configuration: &configuration::Configuration,
1533    backoff: &mut ExponentialBackoff,
1534    group_name: &str,
1535) -> Result<models::BillingCustomer, Error<GetGroupBillingCustomerError>> {
1536    let local_var_configuration = configuration;
1537    // add a prefix to parameters to efficiently prevent name collisions
1538    let p_path_group_name = group_name;
1539
1540    let local_var_client = &local_var_configuration.client;
1541
1542    let local_var_uri_str = format!(
1543        "{}/v1/groups/{groupName}/billingCustomer",
1544        local_var_configuration.qcs_config.api_url(),
1545        groupName = crate::apis::urlencode(p_path_group_name)
1546    );
1547    let mut local_var_req_builder =
1548        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
1549
1550    #[cfg(feature = "tracing")]
1551    {
1552        // Ignore parsing errors if the URL is invalid for some reason.
1553        // If it is invalid, it will turn up as an error later when actually making the request.
1554        let local_var_do_tracing = local_var_uri_str
1555            .parse::<::url::Url>()
1556            .ok()
1557            .is_none_or(|url| {
1558                configuration
1559                    .qcs_config
1560                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1561            });
1562
1563        if local_var_do_tracing {
1564            ::tracing::debug!(
1565                url=%local_var_uri_str,
1566                method="GET",
1567                "making get_group_billing_customer request",
1568            );
1569        }
1570    }
1571
1572    // Use the QCS Bearer token if a client OAuthSession is present,
1573    // but do not require one when the security schema says it is optional.
1574    {
1575        use qcs_api_client_common::configuration::TokenError;
1576
1577        #[allow(
1578            clippy::nonminimal_bool,
1579            clippy::eq_op,
1580            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1581        )]
1582        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1583
1584        let token = local_var_configuration
1585            .qcs_config
1586            .get_bearer_access_token()
1587            .await;
1588
1589        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1590            // the client is configured without any OAuthSession, but this call does not require one.
1591            #[cfg(feature = "tracing")]
1592            tracing::debug!(
1593                "No client credentials found, but this call does not require authentication."
1594            );
1595        } else {
1596            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1597        }
1598    }
1599
1600    let local_var_req = local_var_req_builder.build()?;
1601    let local_var_resp = local_var_client.execute(local_var_req).await?;
1602
1603    let local_var_status = local_var_resp.status();
1604    let local_var_raw_content_type = local_var_resp
1605        .headers()
1606        .get("content-type")
1607        .and_then(|v| v.to_str().ok())
1608        .unwrap_or("application/octet-stream")
1609        .to_string();
1610    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1611
1612    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1613        let local_var_content = local_var_resp.text().await?;
1614        match local_var_content_type {
1615            ContentType::Json => serde_path_to_error::deserialize(
1616                &mut serde_json::Deserializer::from_str(&local_var_content),
1617            )
1618            .map_err(Error::from),
1619            ContentType::Text => Err(Error::InvalidContentType {
1620                content_type: local_var_raw_content_type,
1621                return_type: "models::BillingCustomer",
1622            }),
1623            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1624                content_type: unknown_type,
1625                return_type: "models::BillingCustomer",
1626            }),
1627        }
1628    } else {
1629        let local_var_retry_delay =
1630            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1631        let local_var_content = local_var_resp.text().await?;
1632        let local_var_entity: Option<GetGroupBillingCustomerError> =
1633            serde_json::from_str(&local_var_content).ok();
1634        let local_var_error = ResponseContent {
1635            status: local_var_status,
1636            content: local_var_content,
1637            entity: local_var_entity,
1638            retry_delay: local_var_retry_delay,
1639        };
1640        Err(Error::ResponseError(local_var_error))
1641    }
1642}
1643
1644/// Retrieve billing customer for a QCS group account.
1645pub async fn get_group_billing_customer(
1646    configuration: &configuration::Configuration,
1647    group_name: &str,
1648) -> Result<models::BillingCustomer, Error<GetGroupBillingCustomerError>> {
1649    let mut backoff = configuration.backoff.clone();
1650    let mut refreshed_credentials = false;
1651    let method = reqwest::Method::GET;
1652    loop {
1653        let result =
1654            get_group_billing_customer_inner(configuration, &mut backoff, group_name.clone()).await;
1655
1656        match result {
1657            Ok(result) => return Ok(result),
1658            Err(Error::ResponseError(response)) => {
1659                if !refreshed_credentials
1660                    && matches!(
1661                        response.status,
1662                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1663                    )
1664                {
1665                    // Attempt to refresh credentials
1666                    match configuration.qcs_config.refresh().await {
1667                        Ok(_) => {
1668                            refreshed_credentials = true;
1669                            continue;
1670                        }
1671                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1672                            error,
1673                            oauth_session: _,
1674                        }) => {
1675                            // Token refresh succeeded but persistence failed
1676                            // The token is already in memory and will be used for this request
1677                            #[cfg(feature = "tracing")]
1678                            tracing::warn!(
1679                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1680                                error
1681                            );
1682                            refreshed_credentials = true;
1683                            continue;
1684                        }
1685                        Err(e) => return Err(e.into()),
1686                    }
1687                } else if let Some(duration) = response.retry_delay {
1688                    tokio::time::sleep(duration).await;
1689                    continue;
1690                }
1691
1692                return Err(Error::ResponseError(response));
1693            }
1694            Err(Error::Reqwest(error)) => {
1695                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1696                    tokio::time::sleep(duration).await;
1697                    continue;
1698                }
1699
1700                return Err(Error::Reqwest(error));
1701            }
1702            Err(Error::Io(error)) => {
1703                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1704                    tokio::time::sleep(duration).await;
1705                    continue;
1706                }
1707
1708                return Err(Error::Io(error));
1709            }
1710            Err(error) => return Err(error),
1711        }
1712    }
1713}
1714async fn get_group_upcoming_billing_invoice_inner(
1715    configuration: &configuration::Configuration,
1716    backoff: &mut ExponentialBackoff,
1717    group_name: &str,
1718) -> Result<models::BillingUpcomingInvoice, Error<GetGroupUpcomingBillingInvoiceError>> {
1719    let local_var_configuration = configuration;
1720    // add a prefix to parameters to efficiently prevent name collisions
1721    let p_path_group_name = group_name;
1722
1723    let local_var_client = &local_var_configuration.client;
1724
1725    let local_var_uri_str = format!(
1726        "{}/v1/groups/{groupName}/billingInvoices:getUpcoming",
1727        local_var_configuration.qcs_config.api_url(),
1728        groupName = crate::apis::urlencode(p_path_group_name)
1729    );
1730    let mut local_var_req_builder =
1731        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
1732
1733    #[cfg(feature = "tracing")]
1734    {
1735        // Ignore parsing errors if the URL is invalid for some reason.
1736        // If it is invalid, it will turn up as an error later when actually making the request.
1737        let local_var_do_tracing = local_var_uri_str
1738            .parse::<::url::Url>()
1739            .ok()
1740            .is_none_or(|url| {
1741                configuration
1742                    .qcs_config
1743                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1744            });
1745
1746        if local_var_do_tracing {
1747            ::tracing::debug!(
1748                url=%local_var_uri_str,
1749                method="GET",
1750                "making get_group_upcoming_billing_invoice request",
1751            );
1752        }
1753    }
1754
1755    // Use the QCS Bearer token if a client OAuthSession is present,
1756    // but do not require one when the security schema says it is optional.
1757    {
1758        use qcs_api_client_common::configuration::TokenError;
1759
1760        #[allow(
1761            clippy::nonminimal_bool,
1762            clippy::eq_op,
1763            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1764        )]
1765        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1766
1767        let token = local_var_configuration
1768            .qcs_config
1769            .get_bearer_access_token()
1770            .await;
1771
1772        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1773            // the client is configured without any OAuthSession, but this call does not require one.
1774            #[cfg(feature = "tracing")]
1775            tracing::debug!(
1776                "No client credentials found, but this call does not require authentication."
1777            );
1778        } else {
1779            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1780        }
1781    }
1782
1783    let local_var_req = local_var_req_builder.build()?;
1784    let local_var_resp = local_var_client.execute(local_var_req).await?;
1785
1786    let local_var_status = local_var_resp.status();
1787    let local_var_raw_content_type = local_var_resp
1788        .headers()
1789        .get("content-type")
1790        .and_then(|v| v.to_str().ok())
1791        .unwrap_or("application/octet-stream")
1792        .to_string();
1793    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1794
1795    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1796        let local_var_content = local_var_resp.text().await?;
1797        match local_var_content_type {
1798            ContentType::Json => serde_path_to_error::deserialize(
1799                &mut serde_json::Deserializer::from_str(&local_var_content),
1800            )
1801            .map_err(Error::from),
1802            ContentType::Text => Err(Error::InvalidContentType {
1803                content_type: local_var_raw_content_type,
1804                return_type: "models::BillingUpcomingInvoice",
1805            }),
1806            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1807                content_type: unknown_type,
1808                return_type: "models::BillingUpcomingInvoice",
1809            }),
1810        }
1811    } else {
1812        let local_var_retry_delay =
1813            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1814        let local_var_content = local_var_resp.text().await?;
1815        let local_var_entity: Option<GetGroupUpcomingBillingInvoiceError> =
1816            serde_json::from_str(&local_var_content).ok();
1817        let local_var_error = ResponseContent {
1818            status: local_var_status,
1819            content: local_var_content,
1820            entity: local_var_entity,
1821            retry_delay: local_var_retry_delay,
1822        };
1823        Err(Error::ResponseError(local_var_error))
1824    }
1825}
1826
1827/// Retrieve upcoming invoice for QCS group billing customer.
1828pub async fn get_group_upcoming_billing_invoice(
1829    configuration: &configuration::Configuration,
1830    group_name: &str,
1831) -> Result<models::BillingUpcomingInvoice, Error<GetGroupUpcomingBillingInvoiceError>> {
1832    let mut backoff = configuration.backoff.clone();
1833    let mut refreshed_credentials = false;
1834    let method = reqwest::Method::GET;
1835    loop {
1836        let result = get_group_upcoming_billing_invoice_inner(
1837            configuration,
1838            &mut backoff,
1839            group_name.clone(),
1840        )
1841        .await;
1842
1843        match result {
1844            Ok(result) => return Ok(result),
1845            Err(Error::ResponseError(response)) => {
1846                if !refreshed_credentials
1847                    && matches!(
1848                        response.status,
1849                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1850                    )
1851                {
1852                    // Attempt to refresh credentials
1853                    match configuration.qcs_config.refresh().await {
1854                        Ok(_) => {
1855                            refreshed_credentials = true;
1856                            continue;
1857                        }
1858                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1859                            error,
1860                            oauth_session: _,
1861                        }) => {
1862                            // Token refresh succeeded but persistence failed
1863                            // The token is already in memory and will be used for this request
1864                            #[cfg(feature = "tracing")]
1865                            tracing::warn!(
1866                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1867                                error
1868                            );
1869                            refreshed_credentials = true;
1870                            continue;
1871                        }
1872                        Err(e) => return Err(e.into()),
1873                    }
1874                } else if let Some(duration) = response.retry_delay {
1875                    tokio::time::sleep(duration).await;
1876                    continue;
1877                }
1878
1879                return Err(Error::ResponseError(response));
1880            }
1881            Err(Error::Reqwest(error)) => {
1882                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1883                    tokio::time::sleep(duration).await;
1884                    continue;
1885                }
1886
1887                return Err(Error::Reqwest(error));
1888            }
1889            Err(Error::Io(error)) => {
1890                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1891                    tokio::time::sleep(duration).await;
1892                    continue;
1893                }
1894
1895                return Err(Error::Io(error));
1896            }
1897            Err(error) => return Err(error),
1898        }
1899    }
1900}
1901async fn get_user_balance_inner(
1902    configuration: &configuration::Configuration,
1903    backoff: &mut ExponentialBackoff,
1904    user_id: &str,
1905) -> Result<models::AccountBalance, Error<GetUserBalanceError>> {
1906    let local_var_configuration = configuration;
1907    // add a prefix to parameters to efficiently prevent name collisions
1908    let p_path_user_id = user_id;
1909
1910    let local_var_client = &local_var_configuration.client;
1911
1912    let local_var_uri_str = format!(
1913        "{}/v1/users/{userId}/balance",
1914        local_var_configuration.qcs_config.api_url(),
1915        userId = crate::apis::urlencode(p_path_user_id)
1916    );
1917    let mut local_var_req_builder =
1918        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
1919
1920    #[cfg(feature = "tracing")]
1921    {
1922        // Ignore parsing errors if the URL is invalid for some reason.
1923        // If it is invalid, it will turn up as an error later when actually making the request.
1924        let local_var_do_tracing = local_var_uri_str
1925            .parse::<::url::Url>()
1926            .ok()
1927            .is_none_or(|url| {
1928                configuration
1929                    .qcs_config
1930                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1931            });
1932
1933        if local_var_do_tracing {
1934            ::tracing::debug!(
1935                url=%local_var_uri_str,
1936                method="GET",
1937                "making get_user_balance request",
1938            );
1939        }
1940    }
1941
1942    // Use the QCS Bearer token if a client OAuthSession is present,
1943    // but do not require one when the security schema says it is optional.
1944    {
1945        use qcs_api_client_common::configuration::TokenError;
1946
1947        #[allow(
1948            clippy::nonminimal_bool,
1949            clippy::eq_op,
1950            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1951        )]
1952        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1953
1954        let token = local_var_configuration
1955            .qcs_config
1956            .get_bearer_access_token()
1957            .await;
1958
1959        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1960            // the client is configured without any OAuthSession, but this call does not require one.
1961            #[cfg(feature = "tracing")]
1962            tracing::debug!(
1963                "No client credentials found, but this call does not require authentication."
1964            );
1965        } else {
1966            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1967        }
1968    }
1969
1970    let local_var_req = local_var_req_builder.build()?;
1971    let local_var_resp = local_var_client.execute(local_var_req).await?;
1972
1973    let local_var_status = local_var_resp.status();
1974    let local_var_raw_content_type = local_var_resp
1975        .headers()
1976        .get("content-type")
1977        .and_then(|v| v.to_str().ok())
1978        .unwrap_or("application/octet-stream")
1979        .to_string();
1980    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1981
1982    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1983        let local_var_content = local_var_resp.text().await?;
1984        match local_var_content_type {
1985            ContentType::Json => serde_path_to_error::deserialize(
1986                &mut serde_json::Deserializer::from_str(&local_var_content),
1987            )
1988            .map_err(Error::from),
1989            ContentType::Text => Err(Error::InvalidContentType {
1990                content_type: local_var_raw_content_type,
1991                return_type: "models::AccountBalance",
1992            }),
1993            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1994                content_type: unknown_type,
1995                return_type: "models::AccountBalance",
1996            }),
1997        }
1998    } else {
1999        let local_var_retry_delay =
2000            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2001        let local_var_content = local_var_resp.text().await?;
2002        let local_var_entity: Option<GetUserBalanceError> =
2003            serde_json::from_str(&local_var_content).ok();
2004        let local_var_error = ResponseContent {
2005            status: local_var_status,
2006            content: local_var_content,
2007            entity: local_var_entity,
2008            retry_delay: local_var_retry_delay,
2009        };
2010        Err(Error::ResponseError(local_var_error))
2011    }
2012}
2013
2014/// Retrieve the balance of the requested QCS user account.
2015pub async fn get_user_balance(
2016    configuration: &configuration::Configuration,
2017    user_id: &str,
2018) -> Result<models::AccountBalance, Error<GetUserBalanceError>> {
2019    let mut backoff = configuration.backoff.clone();
2020    let mut refreshed_credentials = false;
2021    let method = reqwest::Method::GET;
2022    loop {
2023        let result = get_user_balance_inner(configuration, &mut backoff, user_id.clone()).await;
2024
2025        match result {
2026            Ok(result) => return Ok(result),
2027            Err(Error::ResponseError(response)) => {
2028                if !refreshed_credentials
2029                    && matches!(
2030                        response.status,
2031                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2032                    )
2033                {
2034                    // Attempt to refresh credentials
2035                    match configuration.qcs_config.refresh().await {
2036                        Ok(_) => {
2037                            refreshed_credentials = true;
2038                            continue;
2039                        }
2040                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2041                            error,
2042                            oauth_session: _,
2043                        }) => {
2044                            // Token refresh succeeded but persistence failed
2045                            // The token is already in memory and will be used for this request
2046                            #[cfg(feature = "tracing")]
2047                            tracing::warn!(
2048                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2049                                error
2050                            );
2051                            refreshed_credentials = true;
2052                            continue;
2053                        }
2054                        Err(e) => return Err(e.into()),
2055                    }
2056                } else if let Some(duration) = response.retry_delay {
2057                    tokio::time::sleep(duration).await;
2058                    continue;
2059                }
2060
2061                return Err(Error::ResponseError(response));
2062            }
2063            Err(Error::Reqwest(error)) => {
2064                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
2065                    tokio::time::sleep(duration).await;
2066                    continue;
2067                }
2068
2069                return Err(Error::Reqwest(error));
2070            }
2071            Err(Error::Io(error)) => {
2072                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
2073                    tokio::time::sleep(duration).await;
2074                    continue;
2075                }
2076
2077                return Err(Error::Io(error));
2078            }
2079            Err(error) => return Err(error),
2080        }
2081    }
2082}
2083async fn get_user_billing_customer_inner(
2084    configuration: &configuration::Configuration,
2085    backoff: &mut ExponentialBackoff,
2086    user_id: &str,
2087) -> Result<models::BillingCustomer, Error<GetUserBillingCustomerError>> {
2088    let local_var_configuration = configuration;
2089    // add a prefix to parameters to efficiently prevent name collisions
2090    let p_path_user_id = user_id;
2091
2092    let local_var_client = &local_var_configuration.client;
2093
2094    let local_var_uri_str = format!(
2095        "{}/v1/users/{userId}/billingCustomer",
2096        local_var_configuration.qcs_config.api_url(),
2097        userId = crate::apis::urlencode(p_path_user_id)
2098    );
2099    let mut local_var_req_builder =
2100        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
2101
2102    #[cfg(feature = "tracing")]
2103    {
2104        // Ignore parsing errors if the URL is invalid for some reason.
2105        // If it is invalid, it will turn up as an error later when actually making the request.
2106        let local_var_do_tracing = local_var_uri_str
2107            .parse::<::url::Url>()
2108            .ok()
2109            .is_none_or(|url| {
2110                configuration
2111                    .qcs_config
2112                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
2113            });
2114
2115        if local_var_do_tracing {
2116            ::tracing::debug!(
2117                url=%local_var_uri_str,
2118                method="GET",
2119                "making get_user_billing_customer request",
2120            );
2121        }
2122    }
2123
2124    // Use the QCS Bearer token if a client OAuthSession is present,
2125    // but do not require one when the security schema says it is optional.
2126    {
2127        use qcs_api_client_common::configuration::TokenError;
2128
2129        #[allow(
2130            clippy::nonminimal_bool,
2131            clippy::eq_op,
2132            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
2133        )]
2134        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
2135
2136        let token = local_var_configuration
2137            .qcs_config
2138            .get_bearer_access_token()
2139            .await;
2140
2141        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
2142            // the client is configured without any OAuthSession, but this call does not require one.
2143            #[cfg(feature = "tracing")]
2144            tracing::debug!(
2145                "No client credentials found, but this call does not require authentication."
2146            );
2147        } else {
2148            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
2149        }
2150    }
2151
2152    let local_var_req = local_var_req_builder.build()?;
2153    let local_var_resp = local_var_client.execute(local_var_req).await?;
2154
2155    let local_var_status = local_var_resp.status();
2156    let local_var_raw_content_type = local_var_resp
2157        .headers()
2158        .get("content-type")
2159        .and_then(|v| v.to_str().ok())
2160        .unwrap_or("application/octet-stream")
2161        .to_string();
2162    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
2163
2164    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
2165        let local_var_content = local_var_resp.text().await?;
2166        match local_var_content_type {
2167            ContentType::Json => serde_path_to_error::deserialize(
2168                &mut serde_json::Deserializer::from_str(&local_var_content),
2169            )
2170            .map_err(Error::from),
2171            ContentType::Text => Err(Error::InvalidContentType {
2172                content_type: local_var_raw_content_type,
2173                return_type: "models::BillingCustomer",
2174            }),
2175            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
2176                content_type: unknown_type,
2177                return_type: "models::BillingCustomer",
2178            }),
2179        }
2180    } else {
2181        let local_var_retry_delay =
2182            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2183        let local_var_content = local_var_resp.text().await?;
2184        let local_var_entity: Option<GetUserBillingCustomerError> =
2185            serde_json::from_str(&local_var_content).ok();
2186        let local_var_error = ResponseContent {
2187            status: local_var_status,
2188            content: local_var_content,
2189            entity: local_var_entity,
2190            retry_delay: local_var_retry_delay,
2191        };
2192        Err(Error::ResponseError(local_var_error))
2193    }
2194}
2195
2196/// Retrieve billing customer for a QCS user account.
2197pub async fn get_user_billing_customer(
2198    configuration: &configuration::Configuration,
2199    user_id: &str,
2200) -> Result<models::BillingCustomer, Error<GetUserBillingCustomerError>> {
2201    let mut backoff = configuration.backoff.clone();
2202    let mut refreshed_credentials = false;
2203    let method = reqwest::Method::GET;
2204    loop {
2205        let result =
2206            get_user_billing_customer_inner(configuration, &mut backoff, user_id.clone()).await;
2207
2208        match result {
2209            Ok(result) => return Ok(result),
2210            Err(Error::ResponseError(response)) => {
2211                if !refreshed_credentials
2212                    && matches!(
2213                        response.status,
2214                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2215                    )
2216                {
2217                    // Attempt to refresh credentials
2218                    match configuration.qcs_config.refresh().await {
2219                        Ok(_) => {
2220                            refreshed_credentials = true;
2221                            continue;
2222                        }
2223                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2224                            error,
2225                            oauth_session: _,
2226                        }) => {
2227                            // Token refresh succeeded but persistence failed
2228                            // The token is already in memory and will be used for this request
2229                            #[cfg(feature = "tracing")]
2230                            tracing::warn!(
2231                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2232                                error
2233                            );
2234                            refreshed_credentials = true;
2235                            continue;
2236                        }
2237                        Err(e) => return Err(e.into()),
2238                    }
2239                } else if let Some(duration) = response.retry_delay {
2240                    tokio::time::sleep(duration).await;
2241                    continue;
2242                }
2243
2244                return Err(Error::ResponseError(response));
2245            }
2246            Err(Error::Reqwest(error)) => {
2247                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
2248                    tokio::time::sleep(duration).await;
2249                    continue;
2250                }
2251
2252                return Err(Error::Reqwest(error));
2253            }
2254            Err(Error::Io(error)) => {
2255                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
2256                    tokio::time::sleep(duration).await;
2257                    continue;
2258                }
2259
2260                return Err(Error::Io(error));
2261            }
2262            Err(error) => return Err(error),
2263        }
2264    }
2265}
2266async fn get_user_event_billing_price_inner(
2267    configuration: &configuration::Configuration,
2268    backoff: &mut ExponentialBackoff,
2269    user_id: &str,
2270    get_account_event_billing_price_request: crate::models::GetAccountEventBillingPriceRequest,
2271) -> Result<models::EventBillingPriceRate, Error<GetUserEventBillingPriceError>> {
2272    let local_var_configuration = configuration;
2273    // add a prefix to parameters to efficiently prevent name collisions
2274    let p_path_user_id = user_id;
2275    let p_body_get_account_event_billing_price_request = get_account_event_billing_price_request;
2276
2277    let local_var_client = &local_var_configuration.client;
2278
2279    let local_var_uri_str = format!(
2280        "{}/v1/users/{userId}/eventBillingPrices:get",
2281        local_var_configuration.qcs_config.api_url(),
2282        userId = crate::apis::urlencode(p_path_user_id)
2283    );
2284    let mut local_var_req_builder =
2285        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
2286
2287    #[cfg(feature = "tracing")]
2288    {
2289        // Ignore parsing errors if the URL is invalid for some reason.
2290        // If it is invalid, it will turn up as an error later when actually making the request.
2291        let local_var_do_tracing = local_var_uri_str
2292            .parse::<::url::Url>()
2293            .ok()
2294            .is_none_or(|url| {
2295                configuration
2296                    .qcs_config
2297                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
2298            });
2299
2300        if local_var_do_tracing {
2301            ::tracing::debug!(
2302                url=%local_var_uri_str,
2303                method="POST",
2304                "making get_user_event_billing_price request",
2305            );
2306        }
2307    }
2308
2309    // Use the QCS Bearer token if a client OAuthSession is present,
2310    // but do not require one when the security schema says it is optional.
2311    {
2312        use qcs_api_client_common::configuration::TokenError;
2313
2314        #[allow(
2315            clippy::nonminimal_bool,
2316            clippy::eq_op,
2317            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
2318        )]
2319        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
2320
2321        let token = local_var_configuration
2322            .qcs_config
2323            .get_bearer_access_token()
2324            .await;
2325
2326        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
2327            // the client is configured without any OAuthSession, but this call does not require one.
2328            #[cfg(feature = "tracing")]
2329            tracing::debug!(
2330                "No client credentials found, but this call does not require authentication."
2331            );
2332        } else {
2333            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
2334        }
2335    }
2336
2337    local_var_req_builder =
2338        local_var_req_builder.json(&p_body_get_account_event_billing_price_request);
2339
2340    let local_var_req = local_var_req_builder.build()?;
2341    let local_var_resp = local_var_client.execute(local_var_req).await?;
2342
2343    let local_var_status = local_var_resp.status();
2344    let local_var_raw_content_type = local_var_resp
2345        .headers()
2346        .get("content-type")
2347        .and_then(|v| v.to_str().ok())
2348        .unwrap_or("application/octet-stream")
2349        .to_string();
2350    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
2351
2352    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
2353        let local_var_content = local_var_resp.text().await?;
2354        match local_var_content_type {
2355            ContentType::Json => serde_path_to_error::deserialize(
2356                &mut serde_json::Deserializer::from_str(&local_var_content),
2357            )
2358            .map_err(Error::from),
2359            ContentType::Text => Err(Error::InvalidContentType {
2360                content_type: local_var_raw_content_type,
2361                return_type: "models::EventBillingPriceRate",
2362            }),
2363            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
2364                content_type: unknown_type,
2365                return_type: "models::EventBillingPriceRate",
2366            }),
2367        }
2368    } else {
2369        let local_var_retry_delay =
2370            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2371        let local_var_content = local_var_resp.text().await?;
2372        let local_var_entity: Option<GetUserEventBillingPriceError> =
2373            serde_json::from_str(&local_var_content).ok();
2374        let local_var_error = ResponseContent {
2375            status: local_var_status,
2376            content: local_var_content,
2377            entity: local_var_entity,
2378            retry_delay: local_var_retry_delay,
2379        };
2380        Err(Error::ResponseError(local_var_error))
2381    }
2382}
2383
2384/// Retrieve `EventBillingPrice` for a user for a specific event. If no price is configured this operation will return a default `EventBillingPrice` for the specified `product`.
2385pub async fn get_user_event_billing_price(
2386    configuration: &configuration::Configuration,
2387    user_id: &str,
2388    get_account_event_billing_price_request: crate::models::GetAccountEventBillingPriceRequest,
2389) -> Result<models::EventBillingPriceRate, Error<GetUserEventBillingPriceError>> {
2390    let mut backoff = configuration.backoff.clone();
2391    let mut refreshed_credentials = false;
2392    let method = reqwest::Method::POST;
2393    loop {
2394        let result = get_user_event_billing_price_inner(
2395            configuration,
2396            &mut backoff,
2397            user_id.clone(),
2398            get_account_event_billing_price_request.clone(),
2399        )
2400        .await;
2401
2402        match result {
2403            Ok(result) => return Ok(result),
2404            Err(Error::ResponseError(response)) => {
2405                if !refreshed_credentials
2406                    && matches!(
2407                        response.status,
2408                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2409                    )
2410                {
2411                    // Attempt to refresh credentials
2412                    match configuration.qcs_config.refresh().await {
2413                        Ok(_) => {
2414                            refreshed_credentials = true;
2415                            continue;
2416                        }
2417                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2418                            error,
2419                            oauth_session: _,
2420                        }) => {
2421                            // Token refresh succeeded but persistence failed
2422                            // The token is already in memory and will be used for this request
2423                            #[cfg(feature = "tracing")]
2424                            tracing::warn!(
2425                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2426                                error
2427                            );
2428                            refreshed_credentials = true;
2429                            continue;
2430                        }
2431                        Err(e) => return Err(e.into()),
2432                    }
2433                } else if let Some(duration) = response.retry_delay {
2434                    tokio::time::sleep(duration).await;
2435                    continue;
2436                }
2437
2438                return Err(Error::ResponseError(response));
2439            }
2440            Err(Error::Reqwest(error)) => {
2441                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
2442                    tokio::time::sleep(duration).await;
2443                    continue;
2444                }
2445
2446                return Err(Error::Reqwest(error));
2447            }
2448            Err(Error::Io(error)) => {
2449                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
2450                    tokio::time::sleep(duration).await;
2451                    continue;
2452                }
2453
2454                return Err(Error::Io(error));
2455            }
2456            Err(error) => return Err(error),
2457        }
2458    }
2459}
2460async fn get_user_upcoming_billing_invoice_inner(
2461    configuration: &configuration::Configuration,
2462    backoff: &mut ExponentialBackoff,
2463    user_id: &str,
2464) -> Result<models::BillingUpcomingInvoice, Error<GetUserUpcomingBillingInvoiceError>> {
2465    let local_var_configuration = configuration;
2466    // add a prefix to parameters to efficiently prevent name collisions
2467    let p_path_user_id = user_id;
2468
2469    let local_var_client = &local_var_configuration.client;
2470
2471    let local_var_uri_str = format!(
2472        "{}/v1/users/{userId}/billingInvoices:getUpcoming",
2473        local_var_configuration.qcs_config.api_url(),
2474        userId = crate::apis::urlencode(p_path_user_id)
2475    );
2476    let mut local_var_req_builder =
2477        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
2478
2479    #[cfg(feature = "tracing")]
2480    {
2481        // Ignore parsing errors if the URL is invalid for some reason.
2482        // If it is invalid, it will turn up as an error later when actually making the request.
2483        let local_var_do_tracing = local_var_uri_str
2484            .parse::<::url::Url>()
2485            .ok()
2486            .is_none_or(|url| {
2487                configuration
2488                    .qcs_config
2489                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
2490            });
2491
2492        if local_var_do_tracing {
2493            ::tracing::debug!(
2494                url=%local_var_uri_str,
2495                method="GET",
2496                "making get_user_upcoming_billing_invoice request",
2497            );
2498        }
2499    }
2500
2501    // Use the QCS Bearer token if a client OAuthSession is present,
2502    // but do not require one when the security schema says it is optional.
2503    {
2504        use qcs_api_client_common::configuration::TokenError;
2505
2506        #[allow(
2507            clippy::nonminimal_bool,
2508            clippy::eq_op,
2509            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
2510        )]
2511        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
2512
2513        let token = local_var_configuration
2514            .qcs_config
2515            .get_bearer_access_token()
2516            .await;
2517
2518        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
2519            // the client is configured without any OAuthSession, but this call does not require one.
2520            #[cfg(feature = "tracing")]
2521            tracing::debug!(
2522                "No client credentials found, but this call does not require authentication."
2523            );
2524        } else {
2525            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
2526        }
2527    }
2528
2529    let local_var_req = local_var_req_builder.build()?;
2530    let local_var_resp = local_var_client.execute(local_var_req).await?;
2531
2532    let local_var_status = local_var_resp.status();
2533    let local_var_raw_content_type = local_var_resp
2534        .headers()
2535        .get("content-type")
2536        .and_then(|v| v.to_str().ok())
2537        .unwrap_or("application/octet-stream")
2538        .to_string();
2539    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
2540
2541    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
2542        let local_var_content = local_var_resp.text().await?;
2543        match local_var_content_type {
2544            ContentType::Json => serde_path_to_error::deserialize(
2545                &mut serde_json::Deserializer::from_str(&local_var_content),
2546            )
2547            .map_err(Error::from),
2548            ContentType::Text => Err(Error::InvalidContentType {
2549                content_type: local_var_raw_content_type,
2550                return_type: "models::BillingUpcomingInvoice",
2551            }),
2552            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
2553                content_type: unknown_type,
2554                return_type: "models::BillingUpcomingInvoice",
2555            }),
2556        }
2557    } else {
2558        let local_var_retry_delay =
2559            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2560        let local_var_content = local_var_resp.text().await?;
2561        let local_var_entity: Option<GetUserUpcomingBillingInvoiceError> =
2562            serde_json::from_str(&local_var_content).ok();
2563        let local_var_error = ResponseContent {
2564            status: local_var_status,
2565            content: local_var_content,
2566            entity: local_var_entity,
2567            retry_delay: local_var_retry_delay,
2568        };
2569        Err(Error::ResponseError(local_var_error))
2570    }
2571}
2572
2573/// Retrieve upcoming invoice for QCS user billing customer.
2574pub async fn get_user_upcoming_billing_invoice(
2575    configuration: &configuration::Configuration,
2576    user_id: &str,
2577) -> Result<models::BillingUpcomingInvoice, Error<GetUserUpcomingBillingInvoiceError>> {
2578    let mut backoff = configuration.backoff.clone();
2579    let mut refreshed_credentials = false;
2580    let method = reqwest::Method::GET;
2581    loop {
2582        let result =
2583            get_user_upcoming_billing_invoice_inner(configuration, &mut backoff, user_id.clone())
2584                .await;
2585
2586        match result {
2587            Ok(result) => return Ok(result),
2588            Err(Error::ResponseError(response)) => {
2589                if !refreshed_credentials
2590                    && matches!(
2591                        response.status,
2592                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2593                    )
2594                {
2595                    // Attempt to refresh credentials
2596                    match configuration.qcs_config.refresh().await {
2597                        Ok(_) => {
2598                            refreshed_credentials = true;
2599                            continue;
2600                        }
2601                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2602                            error,
2603                            oauth_session: _,
2604                        }) => {
2605                            // Token refresh succeeded but persistence failed
2606                            // The token is already in memory and will be used for this request
2607                            #[cfg(feature = "tracing")]
2608                            tracing::warn!(
2609                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2610                                error
2611                            );
2612                            refreshed_credentials = true;
2613                            continue;
2614                        }
2615                        Err(e) => return Err(e.into()),
2616                    }
2617                } else if let Some(duration) = response.retry_delay {
2618                    tokio::time::sleep(duration).await;
2619                    continue;
2620                }
2621
2622                return Err(Error::ResponseError(response));
2623            }
2624            Err(Error::Reqwest(error)) => {
2625                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
2626                    tokio::time::sleep(duration).await;
2627                    continue;
2628                }
2629
2630                return Err(Error::Reqwest(error));
2631            }
2632            Err(Error::Io(error)) => {
2633                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
2634                    tokio::time::sleep(duration).await;
2635                    continue;
2636                }
2637
2638                return Err(Error::Io(error));
2639            }
2640            Err(error) => return Err(error),
2641        }
2642    }
2643}
2644async fn get_viewer_user_onboarding_completed_inner(
2645    configuration: &configuration::Configuration,
2646    backoff: &mut ExponentialBackoff,
2647) -> Result<models::ViewerUserOnboardingCompleted, Error<GetViewerUserOnboardingCompletedError>> {
2648    let local_var_configuration = configuration;
2649
2650    let local_var_client = &local_var_configuration.client;
2651
2652    let local_var_uri_str = format!(
2653        "{}/v1/viewer/onboardingCompleted",
2654        local_var_configuration.qcs_config.api_url()
2655    );
2656    let mut local_var_req_builder =
2657        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
2658
2659    #[cfg(feature = "tracing")]
2660    {
2661        // Ignore parsing errors if the URL is invalid for some reason.
2662        // If it is invalid, it will turn up as an error later when actually making the request.
2663        let local_var_do_tracing = local_var_uri_str
2664            .parse::<::url::Url>()
2665            .ok()
2666            .is_none_or(|url| {
2667                configuration
2668                    .qcs_config
2669                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
2670            });
2671
2672        if local_var_do_tracing {
2673            ::tracing::debug!(
2674                url=%local_var_uri_str,
2675                method="GET",
2676                "making get_viewer_user_onboarding_completed request",
2677            );
2678        }
2679    }
2680
2681    // Use the QCS Bearer token if a client OAuthSession is present,
2682    // but do not require one when the security schema says it is optional.
2683    {
2684        use qcs_api_client_common::configuration::TokenError;
2685
2686        #[allow(
2687            clippy::nonminimal_bool,
2688            clippy::eq_op,
2689            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
2690        )]
2691        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
2692
2693        let token = local_var_configuration
2694            .qcs_config
2695            .get_bearer_access_token()
2696            .await;
2697
2698        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
2699            // the client is configured without any OAuthSession, but this call does not require one.
2700            #[cfg(feature = "tracing")]
2701            tracing::debug!(
2702                "No client credentials found, but this call does not require authentication."
2703            );
2704        } else {
2705            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
2706        }
2707    }
2708
2709    let local_var_req = local_var_req_builder.build()?;
2710    let local_var_resp = local_var_client.execute(local_var_req).await?;
2711
2712    let local_var_status = local_var_resp.status();
2713    let local_var_raw_content_type = local_var_resp
2714        .headers()
2715        .get("content-type")
2716        .and_then(|v| v.to_str().ok())
2717        .unwrap_or("application/octet-stream")
2718        .to_string();
2719    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
2720
2721    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
2722        let local_var_content = local_var_resp.text().await?;
2723        match local_var_content_type {
2724            ContentType::Json => serde_path_to_error::deserialize(
2725                &mut serde_json::Deserializer::from_str(&local_var_content),
2726            )
2727            .map_err(Error::from),
2728            ContentType::Text => Err(Error::InvalidContentType {
2729                content_type: local_var_raw_content_type,
2730                return_type: "models::ViewerUserOnboardingCompleted",
2731            }),
2732            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
2733                content_type: unknown_type,
2734                return_type: "models::ViewerUserOnboardingCompleted",
2735            }),
2736        }
2737    } else {
2738        let local_var_retry_delay =
2739            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2740        let local_var_content = local_var_resp.text().await?;
2741        let local_var_entity: Option<GetViewerUserOnboardingCompletedError> =
2742            serde_json::from_str(&local_var_content).ok();
2743        let local_var_error = ResponseContent {
2744            status: local_var_status,
2745            content: local_var_content,
2746            entity: local_var_entity,
2747            retry_delay: local_var_retry_delay,
2748        };
2749        Err(Error::ResponseError(local_var_error))
2750    }
2751}
2752
2753/// Get the onboarding status of the authenticated user.
2754pub async fn get_viewer_user_onboarding_completed(
2755    configuration: &configuration::Configuration,
2756) -> Result<models::ViewerUserOnboardingCompleted, Error<GetViewerUserOnboardingCompletedError>> {
2757    let mut backoff = configuration.backoff.clone();
2758    let mut refreshed_credentials = false;
2759    let method = reqwest::Method::GET;
2760    loop {
2761        let result = get_viewer_user_onboarding_completed_inner(configuration, &mut backoff).await;
2762
2763        match result {
2764            Ok(result) => return Ok(result),
2765            Err(Error::ResponseError(response)) => {
2766                if !refreshed_credentials
2767                    && matches!(
2768                        response.status,
2769                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2770                    )
2771                {
2772                    // Attempt to refresh credentials
2773                    match configuration.qcs_config.refresh().await {
2774                        Ok(_) => {
2775                            refreshed_credentials = true;
2776                            continue;
2777                        }
2778                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2779                            error,
2780                            oauth_session: _,
2781                        }) => {
2782                            // Token refresh succeeded but persistence failed
2783                            // The token is already in memory and will be used for this request
2784                            #[cfg(feature = "tracing")]
2785                            tracing::warn!(
2786                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2787                                error
2788                            );
2789                            refreshed_credentials = true;
2790                            continue;
2791                        }
2792                        Err(e) => return Err(e.into()),
2793                    }
2794                } else if let Some(duration) = response.retry_delay {
2795                    tokio::time::sleep(duration).await;
2796                    continue;
2797                }
2798
2799                return Err(Error::ResponseError(response));
2800            }
2801            Err(Error::Reqwest(error)) => {
2802                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
2803                    tokio::time::sleep(duration).await;
2804                    continue;
2805                }
2806
2807                return Err(Error::Reqwest(error));
2808            }
2809            Err(Error::Io(error)) => {
2810                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
2811                    tokio::time::sleep(duration).await;
2812                    continue;
2813                }
2814
2815                return Err(Error::Io(error));
2816            }
2817            Err(error) => return Err(error),
2818        }
2819    }
2820}
2821async fn list_group_billing_invoice_lines_inner(
2822    configuration: &configuration::Configuration,
2823    backoff: &mut ExponentialBackoff,
2824    group_name: &str,
2825    billing_invoice_id: &str,
2826    page_token: Option<&str>,
2827    page_size: Option<i64>,
2828) -> Result<models::ListAccountBillingInvoiceLinesResponse, Error<ListGroupBillingInvoiceLinesError>>
2829{
2830    let local_var_configuration = configuration;
2831    // add a prefix to parameters to efficiently prevent name collisions
2832    let p_path_group_name = group_name;
2833    let p_path_billing_invoice_id = billing_invoice_id;
2834    let p_query_page_token = page_token;
2835    let p_query_page_size = page_size;
2836
2837    let local_var_client = &local_var_configuration.client;
2838
2839    let local_var_uri_str = format!(
2840        "{}/v1/groups/{groupName}/billingInvoices/{billingInvoiceId}/lines",
2841        local_var_configuration.qcs_config.api_url(),
2842        groupName = crate::apis::urlencode(p_path_group_name),
2843        billingInvoiceId = crate::apis::urlencode(p_path_billing_invoice_id)
2844    );
2845    let mut local_var_req_builder =
2846        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
2847
2848    #[cfg(feature = "tracing")]
2849    {
2850        // Ignore parsing errors if the URL is invalid for some reason.
2851        // If it is invalid, it will turn up as an error later when actually making the request.
2852        let local_var_do_tracing = local_var_uri_str
2853            .parse::<::url::Url>()
2854            .ok()
2855            .is_none_or(|url| {
2856                configuration
2857                    .qcs_config
2858                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
2859            });
2860
2861        if local_var_do_tracing {
2862            ::tracing::debug!(
2863                url=%local_var_uri_str,
2864                method="GET",
2865                "making list_group_billing_invoice_lines request",
2866            );
2867        }
2868    }
2869
2870    if let Some(ref local_var_str) = p_query_page_token {
2871        local_var_req_builder =
2872            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
2873    }
2874    if let Some(ref local_var_str) = p_query_page_size {
2875        local_var_req_builder =
2876            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
2877    }
2878
2879    // Use the QCS Bearer token if a client OAuthSession is present,
2880    // but do not require one when the security schema says it is optional.
2881    {
2882        use qcs_api_client_common::configuration::TokenError;
2883
2884        #[allow(
2885            clippy::nonminimal_bool,
2886            clippy::eq_op,
2887            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
2888        )]
2889        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
2890
2891        let token = local_var_configuration
2892            .qcs_config
2893            .get_bearer_access_token()
2894            .await;
2895
2896        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
2897            // the client is configured without any OAuthSession, but this call does not require one.
2898            #[cfg(feature = "tracing")]
2899            tracing::debug!(
2900                "No client credentials found, but this call does not require authentication."
2901            );
2902        } else {
2903            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
2904        }
2905    }
2906
2907    let local_var_req = local_var_req_builder.build()?;
2908    let local_var_resp = local_var_client.execute(local_var_req).await?;
2909
2910    let local_var_status = local_var_resp.status();
2911    let local_var_raw_content_type = local_var_resp
2912        .headers()
2913        .get("content-type")
2914        .and_then(|v| v.to_str().ok())
2915        .unwrap_or("application/octet-stream")
2916        .to_string();
2917    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
2918
2919    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
2920        let local_var_content = local_var_resp.text().await?;
2921        match local_var_content_type {
2922            ContentType::Json => serde_path_to_error::deserialize(
2923                &mut serde_json::Deserializer::from_str(&local_var_content),
2924            )
2925            .map_err(Error::from),
2926            ContentType::Text => Err(Error::InvalidContentType {
2927                content_type: local_var_raw_content_type,
2928                return_type: "models::ListAccountBillingInvoiceLinesResponse",
2929            }),
2930            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
2931                content_type: unknown_type,
2932                return_type: "models::ListAccountBillingInvoiceLinesResponse",
2933            }),
2934        }
2935    } else {
2936        let local_var_retry_delay =
2937            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
2938        let local_var_content = local_var_resp.text().await?;
2939        let local_var_entity: Option<ListGroupBillingInvoiceLinesError> =
2940            serde_json::from_str(&local_var_content).ok();
2941        let local_var_error = ResponseContent {
2942            status: local_var_status,
2943            content: local_var_content,
2944            entity: local_var_entity,
2945            retry_delay: local_var_retry_delay,
2946        };
2947        Err(Error::ResponseError(local_var_error))
2948    }
2949}
2950
2951/// Retrieve billing invoice lines for a QCS group account's invoice.
2952pub async fn list_group_billing_invoice_lines(
2953    configuration: &configuration::Configuration,
2954    group_name: &str,
2955    billing_invoice_id: &str,
2956    page_token: Option<&str>,
2957    page_size: Option<i64>,
2958) -> Result<models::ListAccountBillingInvoiceLinesResponse, Error<ListGroupBillingInvoiceLinesError>>
2959{
2960    let mut backoff = configuration.backoff.clone();
2961    let mut refreshed_credentials = false;
2962    let method = reqwest::Method::GET;
2963    loop {
2964        let result = list_group_billing_invoice_lines_inner(
2965            configuration,
2966            &mut backoff,
2967            group_name.clone(),
2968            billing_invoice_id.clone(),
2969            page_token.clone(),
2970            page_size.clone(),
2971        )
2972        .await;
2973
2974        match result {
2975            Ok(result) => return Ok(result),
2976            Err(Error::ResponseError(response)) => {
2977                if !refreshed_credentials
2978                    && matches!(
2979                        response.status,
2980                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
2981                    )
2982                {
2983                    // Attempt to refresh credentials
2984                    match configuration.qcs_config.refresh().await {
2985                        Ok(_) => {
2986                            refreshed_credentials = true;
2987                            continue;
2988                        }
2989                        Err(::qcs_api_client_common::configuration::TokenError::Write {
2990                            error,
2991                            oauth_session: _,
2992                        }) => {
2993                            // Token refresh succeeded but persistence failed
2994                            // The token is already in memory and will be used for this request
2995                            #[cfg(feature = "tracing")]
2996                            tracing::warn!(
2997                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
2998                                error
2999                            );
3000                            refreshed_credentials = true;
3001                            continue;
3002                        }
3003                        Err(e) => return Err(e.into()),
3004                    }
3005                } else if let Some(duration) = response.retry_delay {
3006                    tokio::time::sleep(duration).await;
3007                    continue;
3008                }
3009
3010                return Err(Error::ResponseError(response));
3011            }
3012            Err(Error::Reqwest(error)) => {
3013                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
3014                    tokio::time::sleep(duration).await;
3015                    continue;
3016                }
3017
3018                return Err(Error::Reqwest(error));
3019            }
3020            Err(Error::Io(error)) => {
3021                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
3022                    tokio::time::sleep(duration).await;
3023                    continue;
3024                }
3025
3026                return Err(Error::Io(error));
3027            }
3028            Err(error) => return Err(error),
3029        }
3030    }
3031}
3032async fn list_group_billing_invoices_inner(
3033    configuration: &configuration::Configuration,
3034    backoff: &mut ExponentialBackoff,
3035    group_name: &str,
3036    page_token: Option<&str>,
3037    page_size: Option<i64>,
3038) -> Result<models::ListAccountBillingInvoicesResponse, Error<ListGroupBillingInvoicesError>> {
3039    let local_var_configuration = configuration;
3040    // add a prefix to parameters to efficiently prevent name collisions
3041    let p_path_group_name = group_name;
3042    let p_query_page_token = page_token;
3043    let p_query_page_size = page_size;
3044
3045    let local_var_client = &local_var_configuration.client;
3046
3047    let local_var_uri_str = format!(
3048        "{}/v1/groups/{groupName}/billingInvoices",
3049        local_var_configuration.qcs_config.api_url(),
3050        groupName = crate::apis::urlencode(p_path_group_name)
3051    );
3052    let mut local_var_req_builder =
3053        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
3054
3055    #[cfg(feature = "tracing")]
3056    {
3057        // Ignore parsing errors if the URL is invalid for some reason.
3058        // If it is invalid, it will turn up as an error later when actually making the request.
3059        let local_var_do_tracing = local_var_uri_str
3060            .parse::<::url::Url>()
3061            .ok()
3062            .is_none_or(|url| {
3063                configuration
3064                    .qcs_config
3065                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
3066            });
3067
3068        if local_var_do_tracing {
3069            ::tracing::debug!(
3070                url=%local_var_uri_str,
3071                method="GET",
3072                "making list_group_billing_invoices request",
3073            );
3074        }
3075    }
3076
3077    if let Some(ref local_var_str) = p_query_page_token {
3078        local_var_req_builder =
3079            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
3080    }
3081    if let Some(ref local_var_str) = p_query_page_size {
3082        local_var_req_builder =
3083            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
3084    }
3085
3086    // Use the QCS Bearer token if a client OAuthSession is present,
3087    // but do not require one when the security schema says it is optional.
3088    {
3089        use qcs_api_client_common::configuration::TokenError;
3090
3091        #[allow(
3092            clippy::nonminimal_bool,
3093            clippy::eq_op,
3094            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
3095        )]
3096        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
3097
3098        let token = local_var_configuration
3099            .qcs_config
3100            .get_bearer_access_token()
3101            .await;
3102
3103        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
3104            // the client is configured without any OAuthSession, but this call does not require one.
3105            #[cfg(feature = "tracing")]
3106            tracing::debug!(
3107                "No client credentials found, but this call does not require authentication."
3108            );
3109        } else {
3110            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
3111        }
3112    }
3113
3114    let local_var_req = local_var_req_builder.build()?;
3115    let local_var_resp = local_var_client.execute(local_var_req).await?;
3116
3117    let local_var_status = local_var_resp.status();
3118    let local_var_raw_content_type = local_var_resp
3119        .headers()
3120        .get("content-type")
3121        .and_then(|v| v.to_str().ok())
3122        .unwrap_or("application/octet-stream")
3123        .to_string();
3124    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
3125
3126    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
3127        let local_var_content = local_var_resp.text().await?;
3128        match local_var_content_type {
3129            ContentType::Json => serde_path_to_error::deserialize(
3130                &mut serde_json::Deserializer::from_str(&local_var_content),
3131            )
3132            .map_err(Error::from),
3133            ContentType::Text => Err(Error::InvalidContentType {
3134                content_type: local_var_raw_content_type,
3135                return_type: "models::ListAccountBillingInvoicesResponse",
3136            }),
3137            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
3138                content_type: unknown_type,
3139                return_type: "models::ListAccountBillingInvoicesResponse",
3140            }),
3141        }
3142    } else {
3143        let local_var_retry_delay =
3144            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
3145        let local_var_content = local_var_resp.text().await?;
3146        let local_var_entity: Option<ListGroupBillingInvoicesError> =
3147            serde_json::from_str(&local_var_content).ok();
3148        let local_var_error = ResponseContent {
3149            status: local_var_status,
3150            content: local_var_content,
3151            entity: local_var_entity,
3152            retry_delay: local_var_retry_delay,
3153        };
3154        Err(Error::ResponseError(local_var_error))
3155    }
3156}
3157
3158/// Retrieve billing invoices for a QCS group account.
3159pub async fn list_group_billing_invoices(
3160    configuration: &configuration::Configuration,
3161    group_name: &str,
3162    page_token: Option<&str>,
3163    page_size: Option<i64>,
3164) -> Result<models::ListAccountBillingInvoicesResponse, Error<ListGroupBillingInvoicesError>> {
3165    let mut backoff = configuration.backoff.clone();
3166    let mut refreshed_credentials = false;
3167    let method = reqwest::Method::GET;
3168    loop {
3169        let result = list_group_billing_invoices_inner(
3170            configuration,
3171            &mut backoff,
3172            group_name.clone(),
3173            page_token.clone(),
3174            page_size.clone(),
3175        )
3176        .await;
3177
3178        match result {
3179            Ok(result) => return Ok(result),
3180            Err(Error::ResponseError(response)) => {
3181                if !refreshed_credentials
3182                    && matches!(
3183                        response.status,
3184                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
3185                    )
3186                {
3187                    // Attempt to refresh credentials
3188                    match configuration.qcs_config.refresh().await {
3189                        Ok(_) => {
3190                            refreshed_credentials = true;
3191                            continue;
3192                        }
3193                        Err(::qcs_api_client_common::configuration::TokenError::Write {
3194                            error,
3195                            oauth_session: _,
3196                        }) => {
3197                            // Token refresh succeeded but persistence failed
3198                            // The token is already in memory and will be used for this request
3199                            #[cfg(feature = "tracing")]
3200                            tracing::warn!(
3201                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
3202                                error
3203                            );
3204                            refreshed_credentials = true;
3205                            continue;
3206                        }
3207                        Err(e) => return Err(e.into()),
3208                    }
3209                } else if let Some(duration) = response.retry_delay {
3210                    tokio::time::sleep(duration).await;
3211                    continue;
3212                }
3213
3214                return Err(Error::ResponseError(response));
3215            }
3216            Err(Error::Reqwest(error)) => {
3217                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
3218                    tokio::time::sleep(duration).await;
3219                    continue;
3220                }
3221
3222                return Err(Error::Reqwest(error));
3223            }
3224            Err(Error::Io(error)) => {
3225                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
3226                    tokio::time::sleep(duration).await;
3227                    continue;
3228                }
3229
3230                return Err(Error::Io(error));
3231            }
3232            Err(error) => return Err(error),
3233        }
3234    }
3235}
3236async fn list_group_upcoming_billing_invoice_lines_inner(
3237    configuration: &configuration::Configuration,
3238    backoff: &mut ExponentialBackoff,
3239    group_name: &str,
3240    page_token: Option<&str>,
3241    page_size: Option<i64>,
3242) -> Result<
3243    models::ListAccountBillingInvoiceLinesResponse,
3244    Error<ListGroupUpcomingBillingInvoiceLinesError>,
3245> {
3246    let local_var_configuration = configuration;
3247    // add a prefix to parameters to efficiently prevent name collisions
3248    let p_path_group_name = group_name;
3249    let p_query_page_token = page_token;
3250    let p_query_page_size = page_size;
3251
3252    let local_var_client = &local_var_configuration.client;
3253
3254    let local_var_uri_str = format!(
3255        "{}/v1/groups/{groupName}/billingInvoices:listUpcomingLines",
3256        local_var_configuration.qcs_config.api_url(),
3257        groupName = crate::apis::urlencode(p_path_group_name)
3258    );
3259    let mut local_var_req_builder =
3260        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
3261
3262    #[cfg(feature = "tracing")]
3263    {
3264        // Ignore parsing errors if the URL is invalid for some reason.
3265        // If it is invalid, it will turn up as an error later when actually making the request.
3266        let local_var_do_tracing = local_var_uri_str
3267            .parse::<::url::Url>()
3268            .ok()
3269            .is_none_or(|url| {
3270                configuration
3271                    .qcs_config
3272                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
3273            });
3274
3275        if local_var_do_tracing {
3276            ::tracing::debug!(
3277                url=%local_var_uri_str,
3278                method="GET",
3279                "making list_group_upcoming_billing_invoice_lines request",
3280            );
3281        }
3282    }
3283
3284    if let Some(ref local_var_str) = p_query_page_token {
3285        local_var_req_builder =
3286            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
3287    }
3288    if let Some(ref local_var_str) = p_query_page_size {
3289        local_var_req_builder =
3290            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
3291    }
3292
3293    // Use the QCS Bearer token if a client OAuthSession is present,
3294    // but do not require one when the security schema says it is optional.
3295    {
3296        use qcs_api_client_common::configuration::TokenError;
3297
3298        #[allow(
3299            clippy::nonminimal_bool,
3300            clippy::eq_op,
3301            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
3302        )]
3303        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
3304
3305        let token = local_var_configuration
3306            .qcs_config
3307            .get_bearer_access_token()
3308            .await;
3309
3310        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
3311            // the client is configured without any OAuthSession, but this call does not require one.
3312            #[cfg(feature = "tracing")]
3313            tracing::debug!(
3314                "No client credentials found, but this call does not require authentication."
3315            );
3316        } else {
3317            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
3318        }
3319    }
3320
3321    let local_var_req = local_var_req_builder.build()?;
3322    let local_var_resp = local_var_client.execute(local_var_req).await?;
3323
3324    let local_var_status = local_var_resp.status();
3325    let local_var_raw_content_type = local_var_resp
3326        .headers()
3327        .get("content-type")
3328        .and_then(|v| v.to_str().ok())
3329        .unwrap_or("application/octet-stream")
3330        .to_string();
3331    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
3332
3333    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
3334        let local_var_content = local_var_resp.text().await?;
3335        match local_var_content_type {
3336            ContentType::Json => serde_path_to_error::deserialize(
3337                &mut serde_json::Deserializer::from_str(&local_var_content),
3338            )
3339            .map_err(Error::from),
3340            ContentType::Text => Err(Error::InvalidContentType {
3341                content_type: local_var_raw_content_type,
3342                return_type: "models::ListAccountBillingInvoiceLinesResponse",
3343            }),
3344            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
3345                content_type: unknown_type,
3346                return_type: "models::ListAccountBillingInvoiceLinesResponse",
3347            }),
3348        }
3349    } else {
3350        let local_var_retry_delay =
3351            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
3352        let local_var_content = local_var_resp.text().await?;
3353        let local_var_entity: Option<ListGroupUpcomingBillingInvoiceLinesError> =
3354            serde_json::from_str(&local_var_content).ok();
3355        let local_var_error = ResponseContent {
3356            status: local_var_status,
3357            content: local_var_content,
3358            entity: local_var_entity,
3359            retry_delay: local_var_retry_delay,
3360        };
3361        Err(Error::ResponseError(local_var_error))
3362    }
3363}
3364
3365/// List invoice lines for QCS group billing customer upcoming invoice.
3366pub async fn list_group_upcoming_billing_invoice_lines(
3367    configuration: &configuration::Configuration,
3368    group_name: &str,
3369    page_token: Option<&str>,
3370    page_size: Option<i64>,
3371) -> Result<
3372    models::ListAccountBillingInvoiceLinesResponse,
3373    Error<ListGroupUpcomingBillingInvoiceLinesError>,
3374> {
3375    let mut backoff = configuration.backoff.clone();
3376    let mut refreshed_credentials = false;
3377    let method = reqwest::Method::GET;
3378    loop {
3379        let result = list_group_upcoming_billing_invoice_lines_inner(
3380            configuration,
3381            &mut backoff,
3382            group_name.clone(),
3383            page_token.clone(),
3384            page_size.clone(),
3385        )
3386        .await;
3387
3388        match result {
3389            Ok(result) => return Ok(result),
3390            Err(Error::ResponseError(response)) => {
3391                if !refreshed_credentials
3392                    && matches!(
3393                        response.status,
3394                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
3395                    )
3396                {
3397                    // Attempt to refresh credentials
3398                    match configuration.qcs_config.refresh().await {
3399                        Ok(_) => {
3400                            refreshed_credentials = true;
3401                            continue;
3402                        }
3403                        Err(::qcs_api_client_common::configuration::TokenError::Write {
3404                            error,
3405                            oauth_session: _,
3406                        }) => {
3407                            // Token refresh succeeded but persistence failed
3408                            // The token is already in memory and will be used for this request
3409                            #[cfg(feature = "tracing")]
3410                            tracing::warn!(
3411                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
3412                                error
3413                            );
3414                            refreshed_credentials = true;
3415                            continue;
3416                        }
3417                        Err(e) => return Err(e.into()),
3418                    }
3419                } else if let Some(duration) = response.retry_delay {
3420                    tokio::time::sleep(duration).await;
3421                    continue;
3422                }
3423
3424                return Err(Error::ResponseError(response));
3425            }
3426            Err(Error::Reqwest(error)) => {
3427                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
3428                    tokio::time::sleep(duration).await;
3429                    continue;
3430                }
3431
3432                return Err(Error::Reqwest(error));
3433            }
3434            Err(Error::Io(error)) => {
3435                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
3436                    tokio::time::sleep(duration).await;
3437                    continue;
3438                }
3439
3440                return Err(Error::Io(error));
3441            }
3442            Err(error) => return Err(error),
3443        }
3444    }
3445}
3446async fn list_group_users_inner(
3447    configuration: &configuration::Configuration,
3448    backoff: &mut ExponentialBackoff,
3449    group_name: &str,
3450    page_size: Option<i64>,
3451    page_token: Option<&str>,
3452) -> Result<models::ListGroupUsersResponse, Error<ListGroupUsersError>> {
3453    let local_var_configuration = configuration;
3454    // add a prefix to parameters to efficiently prevent name collisions
3455    let p_path_group_name = group_name;
3456    let p_query_page_size = page_size;
3457    let p_query_page_token = page_token;
3458
3459    let local_var_client = &local_var_configuration.client;
3460
3461    let local_var_uri_str = format!(
3462        "{}/v1/groups/{groupName}/users",
3463        local_var_configuration.qcs_config.api_url(),
3464        groupName = crate::apis::urlencode(p_path_group_name)
3465    );
3466    let mut local_var_req_builder =
3467        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
3468
3469    #[cfg(feature = "tracing")]
3470    {
3471        // Ignore parsing errors if the URL is invalid for some reason.
3472        // If it is invalid, it will turn up as an error later when actually making the request.
3473        let local_var_do_tracing = local_var_uri_str
3474            .parse::<::url::Url>()
3475            .ok()
3476            .is_none_or(|url| {
3477                configuration
3478                    .qcs_config
3479                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
3480            });
3481
3482        if local_var_do_tracing {
3483            ::tracing::debug!(
3484                url=%local_var_uri_str,
3485                method="GET",
3486                "making list_group_users request",
3487            );
3488        }
3489    }
3490
3491    if let Some(ref local_var_str) = p_query_page_size {
3492        local_var_req_builder =
3493            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
3494    }
3495    if let Some(ref local_var_str) = p_query_page_token {
3496        local_var_req_builder =
3497            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
3498    }
3499
3500    // Use the QCS Bearer token if a client OAuthSession is present,
3501    // but do not require one when the security schema says it is optional.
3502    {
3503        use qcs_api_client_common::configuration::TokenError;
3504
3505        #[allow(
3506            clippy::nonminimal_bool,
3507            clippy::eq_op,
3508            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
3509        )]
3510        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
3511
3512        let token = local_var_configuration
3513            .qcs_config
3514            .get_bearer_access_token()
3515            .await;
3516
3517        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
3518            // the client is configured without any OAuthSession, but this call does not require one.
3519            #[cfg(feature = "tracing")]
3520            tracing::debug!(
3521                "No client credentials found, but this call does not require authentication."
3522            );
3523        } else {
3524            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
3525        }
3526    }
3527
3528    let local_var_req = local_var_req_builder.build()?;
3529    let local_var_resp = local_var_client.execute(local_var_req).await?;
3530
3531    let local_var_status = local_var_resp.status();
3532    let local_var_raw_content_type = local_var_resp
3533        .headers()
3534        .get("content-type")
3535        .and_then(|v| v.to_str().ok())
3536        .unwrap_or("application/octet-stream")
3537        .to_string();
3538    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
3539
3540    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
3541        let local_var_content = local_var_resp.text().await?;
3542        match local_var_content_type {
3543            ContentType::Json => serde_path_to_error::deserialize(
3544                &mut serde_json::Deserializer::from_str(&local_var_content),
3545            )
3546            .map_err(Error::from),
3547            ContentType::Text => Err(Error::InvalidContentType {
3548                content_type: local_var_raw_content_type,
3549                return_type: "models::ListGroupUsersResponse",
3550            }),
3551            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
3552                content_type: unknown_type,
3553                return_type: "models::ListGroupUsersResponse",
3554            }),
3555        }
3556    } else {
3557        let local_var_retry_delay =
3558            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
3559        let local_var_content = local_var_resp.text().await?;
3560        let local_var_entity: Option<ListGroupUsersError> =
3561            serde_json::from_str(&local_var_content).ok();
3562        let local_var_error = ResponseContent {
3563            status: local_var_status,
3564            content: local_var_content,
3565            entity: local_var_entity,
3566            retry_delay: local_var_retry_delay,
3567        };
3568        Err(Error::ResponseError(local_var_error))
3569    }
3570}
3571
3572/// List users belonging to a group. Note, group membership may take several minutes to update within our identity provider. After adding or removing a user to or from a group, please allow up to 60 minutes for changes to be reflected.
3573pub async fn list_group_users(
3574    configuration: &configuration::Configuration,
3575    group_name: &str,
3576    page_size: Option<i64>,
3577    page_token: Option<&str>,
3578) -> Result<models::ListGroupUsersResponse, Error<ListGroupUsersError>> {
3579    let mut backoff = configuration.backoff.clone();
3580    let mut refreshed_credentials = false;
3581    let method = reqwest::Method::GET;
3582    loop {
3583        let result = list_group_users_inner(
3584            configuration,
3585            &mut backoff,
3586            group_name.clone(),
3587            page_size.clone(),
3588            page_token.clone(),
3589        )
3590        .await;
3591
3592        match result {
3593            Ok(result) => return Ok(result),
3594            Err(Error::ResponseError(response)) => {
3595                if !refreshed_credentials
3596                    && matches!(
3597                        response.status,
3598                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
3599                    )
3600                {
3601                    // Attempt to refresh credentials
3602                    match configuration.qcs_config.refresh().await {
3603                        Ok(_) => {
3604                            refreshed_credentials = true;
3605                            continue;
3606                        }
3607                        Err(::qcs_api_client_common::configuration::TokenError::Write {
3608                            error,
3609                            oauth_session: _,
3610                        }) => {
3611                            // Token refresh succeeded but persistence failed
3612                            // The token is already in memory and will be used for this request
3613                            #[cfg(feature = "tracing")]
3614                            tracing::warn!(
3615                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
3616                                error
3617                            );
3618                            refreshed_credentials = true;
3619                            continue;
3620                        }
3621                        Err(e) => return Err(e.into()),
3622                    }
3623                } else if let Some(duration) = response.retry_delay {
3624                    tokio::time::sleep(duration).await;
3625                    continue;
3626                }
3627
3628                return Err(Error::ResponseError(response));
3629            }
3630            Err(Error::Reqwest(error)) => {
3631                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
3632                    tokio::time::sleep(duration).await;
3633                    continue;
3634                }
3635
3636                return Err(Error::Reqwest(error));
3637            }
3638            Err(Error::Io(error)) => {
3639                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
3640                    tokio::time::sleep(duration).await;
3641                    continue;
3642                }
3643
3644                return Err(Error::Io(error));
3645            }
3646            Err(error) => return Err(error),
3647        }
3648    }
3649}
3650async fn list_user_billing_invoice_lines_inner(
3651    configuration: &configuration::Configuration,
3652    backoff: &mut ExponentialBackoff,
3653    user_id: &str,
3654    billing_invoice_id: &str,
3655    page_token: Option<&str>,
3656    page_size: Option<i64>,
3657) -> Result<models::ListAccountBillingInvoiceLinesResponse, Error<ListUserBillingInvoiceLinesError>>
3658{
3659    let local_var_configuration = configuration;
3660    // add a prefix to parameters to efficiently prevent name collisions
3661    let p_path_user_id = user_id;
3662    let p_path_billing_invoice_id = billing_invoice_id;
3663    let p_query_page_token = page_token;
3664    let p_query_page_size = page_size;
3665
3666    let local_var_client = &local_var_configuration.client;
3667
3668    let local_var_uri_str = format!(
3669        "{}/v1/users/{userId}/billingInvoices/{billingInvoiceId}/lines",
3670        local_var_configuration.qcs_config.api_url(),
3671        userId = crate::apis::urlencode(p_path_user_id),
3672        billingInvoiceId = crate::apis::urlencode(p_path_billing_invoice_id)
3673    );
3674    let mut local_var_req_builder =
3675        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
3676
3677    #[cfg(feature = "tracing")]
3678    {
3679        // Ignore parsing errors if the URL is invalid for some reason.
3680        // If it is invalid, it will turn up as an error later when actually making the request.
3681        let local_var_do_tracing = local_var_uri_str
3682            .parse::<::url::Url>()
3683            .ok()
3684            .is_none_or(|url| {
3685                configuration
3686                    .qcs_config
3687                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
3688            });
3689
3690        if local_var_do_tracing {
3691            ::tracing::debug!(
3692                url=%local_var_uri_str,
3693                method="GET",
3694                "making list_user_billing_invoice_lines request",
3695            );
3696        }
3697    }
3698
3699    if let Some(ref local_var_str) = p_query_page_token {
3700        local_var_req_builder =
3701            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
3702    }
3703    if let Some(ref local_var_str) = p_query_page_size {
3704        local_var_req_builder =
3705            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
3706    }
3707
3708    // Use the QCS Bearer token if a client OAuthSession is present,
3709    // but do not require one when the security schema says it is optional.
3710    {
3711        use qcs_api_client_common::configuration::TokenError;
3712
3713        #[allow(
3714            clippy::nonminimal_bool,
3715            clippy::eq_op,
3716            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
3717        )]
3718        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
3719
3720        let token = local_var_configuration
3721            .qcs_config
3722            .get_bearer_access_token()
3723            .await;
3724
3725        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
3726            // the client is configured without any OAuthSession, but this call does not require one.
3727            #[cfg(feature = "tracing")]
3728            tracing::debug!(
3729                "No client credentials found, but this call does not require authentication."
3730            );
3731        } else {
3732            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
3733        }
3734    }
3735
3736    let local_var_req = local_var_req_builder.build()?;
3737    let local_var_resp = local_var_client.execute(local_var_req).await?;
3738
3739    let local_var_status = local_var_resp.status();
3740    let local_var_raw_content_type = local_var_resp
3741        .headers()
3742        .get("content-type")
3743        .and_then(|v| v.to_str().ok())
3744        .unwrap_or("application/octet-stream")
3745        .to_string();
3746    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
3747
3748    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
3749        let local_var_content = local_var_resp.text().await?;
3750        match local_var_content_type {
3751            ContentType::Json => serde_path_to_error::deserialize(
3752                &mut serde_json::Deserializer::from_str(&local_var_content),
3753            )
3754            .map_err(Error::from),
3755            ContentType::Text => Err(Error::InvalidContentType {
3756                content_type: local_var_raw_content_type,
3757                return_type: "models::ListAccountBillingInvoiceLinesResponse",
3758            }),
3759            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
3760                content_type: unknown_type,
3761                return_type: "models::ListAccountBillingInvoiceLinesResponse",
3762            }),
3763        }
3764    } else {
3765        let local_var_retry_delay =
3766            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
3767        let local_var_content = local_var_resp.text().await?;
3768        let local_var_entity: Option<ListUserBillingInvoiceLinesError> =
3769            serde_json::from_str(&local_var_content).ok();
3770        let local_var_error = ResponseContent {
3771            status: local_var_status,
3772            content: local_var_content,
3773            entity: local_var_entity,
3774            retry_delay: local_var_retry_delay,
3775        };
3776        Err(Error::ResponseError(local_var_error))
3777    }
3778}
3779
3780/// Retrieve billing invoice lines for a QCS user account's invoice.
3781pub async fn list_user_billing_invoice_lines(
3782    configuration: &configuration::Configuration,
3783    user_id: &str,
3784    billing_invoice_id: &str,
3785    page_token: Option<&str>,
3786    page_size: Option<i64>,
3787) -> Result<models::ListAccountBillingInvoiceLinesResponse, Error<ListUserBillingInvoiceLinesError>>
3788{
3789    let mut backoff = configuration.backoff.clone();
3790    let mut refreshed_credentials = false;
3791    let method = reqwest::Method::GET;
3792    loop {
3793        let result = list_user_billing_invoice_lines_inner(
3794            configuration,
3795            &mut backoff,
3796            user_id.clone(),
3797            billing_invoice_id.clone(),
3798            page_token.clone(),
3799            page_size.clone(),
3800        )
3801        .await;
3802
3803        match result {
3804            Ok(result) => return Ok(result),
3805            Err(Error::ResponseError(response)) => {
3806                if !refreshed_credentials
3807                    && matches!(
3808                        response.status,
3809                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
3810                    )
3811                {
3812                    // Attempt to refresh credentials
3813                    match configuration.qcs_config.refresh().await {
3814                        Ok(_) => {
3815                            refreshed_credentials = true;
3816                            continue;
3817                        }
3818                        Err(::qcs_api_client_common::configuration::TokenError::Write {
3819                            error,
3820                            oauth_session: _,
3821                        }) => {
3822                            // Token refresh succeeded but persistence failed
3823                            // The token is already in memory and will be used for this request
3824                            #[cfg(feature = "tracing")]
3825                            tracing::warn!(
3826                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
3827                                error
3828                            );
3829                            refreshed_credentials = true;
3830                            continue;
3831                        }
3832                        Err(e) => return Err(e.into()),
3833                    }
3834                } else if let Some(duration) = response.retry_delay {
3835                    tokio::time::sleep(duration).await;
3836                    continue;
3837                }
3838
3839                return Err(Error::ResponseError(response));
3840            }
3841            Err(Error::Reqwest(error)) => {
3842                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
3843                    tokio::time::sleep(duration).await;
3844                    continue;
3845                }
3846
3847                return Err(Error::Reqwest(error));
3848            }
3849            Err(Error::Io(error)) => {
3850                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
3851                    tokio::time::sleep(duration).await;
3852                    continue;
3853                }
3854
3855                return Err(Error::Io(error));
3856            }
3857            Err(error) => return Err(error),
3858        }
3859    }
3860}
3861async fn list_user_billing_invoices_inner(
3862    configuration: &configuration::Configuration,
3863    backoff: &mut ExponentialBackoff,
3864    user_id: &str,
3865    page_token: Option<&str>,
3866    page_size: Option<i64>,
3867) -> Result<models::ListAccountBillingInvoicesResponse, Error<ListUserBillingInvoicesError>> {
3868    let local_var_configuration = configuration;
3869    // add a prefix to parameters to efficiently prevent name collisions
3870    let p_path_user_id = user_id;
3871    let p_query_page_token = page_token;
3872    let p_query_page_size = page_size;
3873
3874    let local_var_client = &local_var_configuration.client;
3875
3876    let local_var_uri_str = format!(
3877        "{}/v1/users/{userId}/billingInvoices",
3878        local_var_configuration.qcs_config.api_url(),
3879        userId = crate::apis::urlencode(p_path_user_id)
3880    );
3881    let mut local_var_req_builder =
3882        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
3883
3884    #[cfg(feature = "tracing")]
3885    {
3886        // Ignore parsing errors if the URL is invalid for some reason.
3887        // If it is invalid, it will turn up as an error later when actually making the request.
3888        let local_var_do_tracing = local_var_uri_str
3889            .parse::<::url::Url>()
3890            .ok()
3891            .is_none_or(|url| {
3892                configuration
3893                    .qcs_config
3894                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
3895            });
3896
3897        if local_var_do_tracing {
3898            ::tracing::debug!(
3899                url=%local_var_uri_str,
3900                method="GET",
3901                "making list_user_billing_invoices request",
3902            );
3903        }
3904    }
3905
3906    if let Some(ref local_var_str) = p_query_page_token {
3907        local_var_req_builder =
3908            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
3909    }
3910    if let Some(ref local_var_str) = p_query_page_size {
3911        local_var_req_builder =
3912            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
3913    }
3914
3915    // Use the QCS Bearer token if a client OAuthSession is present,
3916    // but do not require one when the security schema says it is optional.
3917    {
3918        use qcs_api_client_common::configuration::TokenError;
3919
3920        #[allow(
3921            clippy::nonminimal_bool,
3922            clippy::eq_op,
3923            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
3924        )]
3925        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
3926
3927        let token = local_var_configuration
3928            .qcs_config
3929            .get_bearer_access_token()
3930            .await;
3931
3932        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
3933            // the client is configured without any OAuthSession, but this call does not require one.
3934            #[cfg(feature = "tracing")]
3935            tracing::debug!(
3936                "No client credentials found, but this call does not require authentication."
3937            );
3938        } else {
3939            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
3940        }
3941    }
3942
3943    let local_var_req = local_var_req_builder.build()?;
3944    let local_var_resp = local_var_client.execute(local_var_req).await?;
3945
3946    let local_var_status = local_var_resp.status();
3947    let local_var_raw_content_type = local_var_resp
3948        .headers()
3949        .get("content-type")
3950        .and_then(|v| v.to_str().ok())
3951        .unwrap_or("application/octet-stream")
3952        .to_string();
3953    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
3954
3955    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
3956        let local_var_content = local_var_resp.text().await?;
3957        match local_var_content_type {
3958            ContentType::Json => serde_path_to_error::deserialize(
3959                &mut serde_json::Deserializer::from_str(&local_var_content),
3960            )
3961            .map_err(Error::from),
3962            ContentType::Text => Err(Error::InvalidContentType {
3963                content_type: local_var_raw_content_type,
3964                return_type: "models::ListAccountBillingInvoicesResponse",
3965            }),
3966            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
3967                content_type: unknown_type,
3968                return_type: "models::ListAccountBillingInvoicesResponse",
3969            }),
3970        }
3971    } else {
3972        let local_var_retry_delay =
3973            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
3974        let local_var_content = local_var_resp.text().await?;
3975        let local_var_entity: Option<ListUserBillingInvoicesError> =
3976            serde_json::from_str(&local_var_content).ok();
3977        let local_var_error = ResponseContent {
3978            status: local_var_status,
3979            content: local_var_content,
3980            entity: local_var_entity,
3981            retry_delay: local_var_retry_delay,
3982        };
3983        Err(Error::ResponseError(local_var_error))
3984    }
3985}
3986
3987/// Retrieve billing invoices for a QCS user account.
3988pub async fn list_user_billing_invoices(
3989    configuration: &configuration::Configuration,
3990    user_id: &str,
3991    page_token: Option<&str>,
3992    page_size: Option<i64>,
3993) -> Result<models::ListAccountBillingInvoicesResponse, Error<ListUserBillingInvoicesError>> {
3994    let mut backoff = configuration.backoff.clone();
3995    let mut refreshed_credentials = false;
3996    let method = reqwest::Method::GET;
3997    loop {
3998        let result = list_user_billing_invoices_inner(
3999            configuration,
4000            &mut backoff,
4001            user_id.clone(),
4002            page_token.clone(),
4003            page_size.clone(),
4004        )
4005        .await;
4006
4007        match result {
4008            Ok(result) => return Ok(result),
4009            Err(Error::ResponseError(response)) => {
4010                if !refreshed_credentials
4011                    && matches!(
4012                        response.status,
4013                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4014                    )
4015                {
4016                    // Attempt to refresh credentials
4017                    match configuration.qcs_config.refresh().await {
4018                        Ok(_) => {
4019                            refreshed_credentials = true;
4020                            continue;
4021                        }
4022                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4023                            error,
4024                            oauth_session: _,
4025                        }) => {
4026                            // Token refresh succeeded but persistence failed
4027                            // The token is already in memory and will be used for this request
4028                            #[cfg(feature = "tracing")]
4029                            tracing::warn!(
4030                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
4031                                error
4032                            );
4033                            refreshed_credentials = true;
4034                            continue;
4035                        }
4036                        Err(e) => return Err(e.into()),
4037                    }
4038                } else if let Some(duration) = response.retry_delay {
4039                    tokio::time::sleep(duration).await;
4040                    continue;
4041                }
4042
4043                return Err(Error::ResponseError(response));
4044            }
4045            Err(Error::Reqwest(error)) => {
4046                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
4047                    tokio::time::sleep(duration).await;
4048                    continue;
4049                }
4050
4051                return Err(Error::Reqwest(error));
4052            }
4053            Err(Error::Io(error)) => {
4054                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
4055                    tokio::time::sleep(duration).await;
4056                    continue;
4057                }
4058
4059                return Err(Error::Io(error));
4060            }
4061            Err(error) => return Err(error),
4062        }
4063    }
4064}
4065async fn list_user_groups_inner(
4066    configuration: &configuration::Configuration,
4067    backoff: &mut ExponentialBackoff,
4068    user_id: &str,
4069    page_size: Option<i64>,
4070    page_token: Option<&str>,
4071) -> Result<models::ListGroupsResponse, Error<ListUserGroupsError>> {
4072    let local_var_configuration = configuration;
4073    // add a prefix to parameters to efficiently prevent name collisions
4074    let p_path_user_id = user_id;
4075    let p_query_page_size = page_size;
4076    let p_query_page_token = page_token;
4077
4078    let local_var_client = &local_var_configuration.client;
4079
4080    let local_var_uri_str = format!(
4081        "{}/v1/users/{userId}/groups",
4082        local_var_configuration.qcs_config.api_url(),
4083        userId = crate::apis::urlencode(p_path_user_id)
4084    );
4085    let mut local_var_req_builder =
4086        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
4087
4088    #[cfg(feature = "tracing")]
4089    {
4090        // Ignore parsing errors if the URL is invalid for some reason.
4091        // If it is invalid, it will turn up as an error later when actually making the request.
4092        let local_var_do_tracing = local_var_uri_str
4093            .parse::<::url::Url>()
4094            .ok()
4095            .is_none_or(|url| {
4096                configuration
4097                    .qcs_config
4098                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
4099            });
4100
4101        if local_var_do_tracing {
4102            ::tracing::debug!(
4103                url=%local_var_uri_str,
4104                method="GET",
4105                "making list_user_groups request",
4106            );
4107        }
4108    }
4109
4110    if let Some(ref local_var_str) = p_query_page_size {
4111        local_var_req_builder =
4112            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
4113    }
4114    if let Some(ref local_var_str) = p_query_page_token {
4115        local_var_req_builder =
4116            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
4117    }
4118
4119    // Use the QCS Bearer token if a client OAuthSession is present,
4120    // but do not require one when the security schema says it is optional.
4121    {
4122        use qcs_api_client_common::configuration::TokenError;
4123
4124        #[allow(
4125            clippy::nonminimal_bool,
4126            clippy::eq_op,
4127            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
4128        )]
4129        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
4130
4131        let token = local_var_configuration
4132            .qcs_config
4133            .get_bearer_access_token()
4134            .await;
4135
4136        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
4137            // the client is configured without any OAuthSession, but this call does not require one.
4138            #[cfg(feature = "tracing")]
4139            tracing::debug!(
4140                "No client credentials found, but this call does not require authentication."
4141            );
4142        } else {
4143            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
4144        }
4145    }
4146
4147    let local_var_req = local_var_req_builder.build()?;
4148    let local_var_resp = local_var_client.execute(local_var_req).await?;
4149
4150    let local_var_status = local_var_resp.status();
4151    let local_var_raw_content_type = local_var_resp
4152        .headers()
4153        .get("content-type")
4154        .and_then(|v| v.to_str().ok())
4155        .unwrap_or("application/octet-stream")
4156        .to_string();
4157    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
4158
4159    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
4160        let local_var_content = local_var_resp.text().await?;
4161        match local_var_content_type {
4162            ContentType::Json => serde_path_to_error::deserialize(
4163                &mut serde_json::Deserializer::from_str(&local_var_content),
4164            )
4165            .map_err(Error::from),
4166            ContentType::Text => Err(Error::InvalidContentType {
4167                content_type: local_var_raw_content_type,
4168                return_type: "models::ListGroupsResponse",
4169            }),
4170            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
4171                content_type: unknown_type,
4172                return_type: "models::ListGroupsResponse",
4173            }),
4174        }
4175    } else {
4176        let local_var_retry_delay =
4177            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
4178        let local_var_content = local_var_resp.text().await?;
4179        let local_var_entity: Option<ListUserGroupsError> =
4180            serde_json::from_str(&local_var_content).ok();
4181        let local_var_error = ResponseContent {
4182            status: local_var_status,
4183            content: local_var_content,
4184            entity: local_var_entity,
4185            retry_delay: local_var_retry_delay,
4186        };
4187        Err(Error::ResponseError(local_var_error))
4188    }
4189}
4190
4191/// List QCS groups for the requested user
4192pub async fn list_user_groups(
4193    configuration: &configuration::Configuration,
4194    user_id: &str,
4195    page_size: Option<i64>,
4196    page_token: Option<&str>,
4197) -> Result<models::ListGroupsResponse, Error<ListUserGroupsError>> {
4198    let mut backoff = configuration.backoff.clone();
4199    let mut refreshed_credentials = false;
4200    let method = reqwest::Method::GET;
4201    loop {
4202        let result = list_user_groups_inner(
4203            configuration,
4204            &mut backoff,
4205            user_id.clone(),
4206            page_size.clone(),
4207            page_token.clone(),
4208        )
4209        .await;
4210
4211        match result {
4212            Ok(result) => return Ok(result),
4213            Err(Error::ResponseError(response)) => {
4214                if !refreshed_credentials
4215                    && matches!(
4216                        response.status,
4217                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4218                    )
4219                {
4220                    // Attempt to refresh credentials
4221                    match configuration.qcs_config.refresh().await {
4222                        Ok(_) => {
4223                            refreshed_credentials = true;
4224                            continue;
4225                        }
4226                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4227                            error,
4228                            oauth_session: _,
4229                        }) => {
4230                            // Token refresh succeeded but persistence failed
4231                            // The token is already in memory and will be used for this request
4232                            #[cfg(feature = "tracing")]
4233                            tracing::warn!(
4234                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
4235                                error
4236                            );
4237                            refreshed_credentials = true;
4238                            continue;
4239                        }
4240                        Err(e) => return Err(e.into()),
4241                    }
4242                } else if let Some(duration) = response.retry_delay {
4243                    tokio::time::sleep(duration).await;
4244                    continue;
4245                }
4246
4247                return Err(Error::ResponseError(response));
4248            }
4249            Err(Error::Reqwest(error)) => {
4250                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
4251                    tokio::time::sleep(duration).await;
4252                    continue;
4253                }
4254
4255                return Err(Error::Reqwest(error));
4256            }
4257            Err(Error::Io(error)) => {
4258                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
4259                    tokio::time::sleep(duration).await;
4260                    continue;
4261                }
4262
4263                return Err(Error::Io(error));
4264            }
4265            Err(error) => return Err(error),
4266        }
4267    }
4268}
4269async fn list_user_upcoming_billing_invoice_lines_inner(
4270    configuration: &configuration::Configuration,
4271    backoff: &mut ExponentialBackoff,
4272    user_id: &str,
4273    page_token: Option<&str>,
4274    page_size: Option<i64>,
4275) -> Result<
4276    models::ListAccountBillingInvoiceLinesResponse,
4277    Error<ListUserUpcomingBillingInvoiceLinesError>,
4278> {
4279    let local_var_configuration = configuration;
4280    // add a prefix to parameters to efficiently prevent name collisions
4281    let p_path_user_id = user_id;
4282    let p_query_page_token = page_token;
4283    let p_query_page_size = page_size;
4284
4285    let local_var_client = &local_var_configuration.client;
4286
4287    let local_var_uri_str = format!(
4288        "{}/v1/users/{userId}/billingInvoices:listUpcomingLines",
4289        local_var_configuration.qcs_config.api_url(),
4290        userId = crate::apis::urlencode(p_path_user_id)
4291    );
4292    let mut local_var_req_builder =
4293        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
4294
4295    #[cfg(feature = "tracing")]
4296    {
4297        // Ignore parsing errors if the URL is invalid for some reason.
4298        // If it is invalid, it will turn up as an error later when actually making the request.
4299        let local_var_do_tracing = local_var_uri_str
4300            .parse::<::url::Url>()
4301            .ok()
4302            .is_none_or(|url| {
4303                configuration
4304                    .qcs_config
4305                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
4306            });
4307
4308        if local_var_do_tracing {
4309            ::tracing::debug!(
4310                url=%local_var_uri_str,
4311                method="GET",
4312                "making list_user_upcoming_billing_invoice_lines request",
4313            );
4314        }
4315    }
4316
4317    if let Some(ref local_var_str) = p_query_page_token {
4318        local_var_req_builder =
4319            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
4320    }
4321    if let Some(ref local_var_str) = p_query_page_size {
4322        local_var_req_builder =
4323            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
4324    }
4325
4326    // Use the QCS Bearer token if a client OAuthSession is present,
4327    // but do not require one when the security schema says it is optional.
4328    {
4329        use qcs_api_client_common::configuration::TokenError;
4330
4331        #[allow(
4332            clippy::nonminimal_bool,
4333            clippy::eq_op,
4334            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
4335        )]
4336        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
4337
4338        let token = local_var_configuration
4339            .qcs_config
4340            .get_bearer_access_token()
4341            .await;
4342
4343        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
4344            // the client is configured without any OAuthSession, but this call does not require one.
4345            #[cfg(feature = "tracing")]
4346            tracing::debug!(
4347                "No client credentials found, but this call does not require authentication."
4348            );
4349        } else {
4350            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
4351        }
4352    }
4353
4354    let local_var_req = local_var_req_builder.build()?;
4355    let local_var_resp = local_var_client.execute(local_var_req).await?;
4356
4357    let local_var_status = local_var_resp.status();
4358    let local_var_raw_content_type = local_var_resp
4359        .headers()
4360        .get("content-type")
4361        .and_then(|v| v.to_str().ok())
4362        .unwrap_or("application/octet-stream")
4363        .to_string();
4364    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
4365
4366    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
4367        let local_var_content = local_var_resp.text().await?;
4368        match local_var_content_type {
4369            ContentType::Json => serde_path_to_error::deserialize(
4370                &mut serde_json::Deserializer::from_str(&local_var_content),
4371            )
4372            .map_err(Error::from),
4373            ContentType::Text => Err(Error::InvalidContentType {
4374                content_type: local_var_raw_content_type,
4375                return_type: "models::ListAccountBillingInvoiceLinesResponse",
4376            }),
4377            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
4378                content_type: unknown_type,
4379                return_type: "models::ListAccountBillingInvoiceLinesResponse",
4380            }),
4381        }
4382    } else {
4383        let local_var_retry_delay =
4384            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
4385        let local_var_content = local_var_resp.text().await?;
4386        let local_var_entity: Option<ListUserUpcomingBillingInvoiceLinesError> =
4387            serde_json::from_str(&local_var_content).ok();
4388        let local_var_error = ResponseContent {
4389            status: local_var_status,
4390            content: local_var_content,
4391            entity: local_var_entity,
4392            retry_delay: local_var_retry_delay,
4393        };
4394        Err(Error::ResponseError(local_var_error))
4395    }
4396}
4397
4398/// List invoice lines for QCS user billing customer upcoming invoice.
4399pub async fn list_user_upcoming_billing_invoice_lines(
4400    configuration: &configuration::Configuration,
4401    user_id: &str,
4402    page_token: Option<&str>,
4403    page_size: Option<i64>,
4404) -> Result<
4405    models::ListAccountBillingInvoiceLinesResponse,
4406    Error<ListUserUpcomingBillingInvoiceLinesError>,
4407> {
4408    let mut backoff = configuration.backoff.clone();
4409    let mut refreshed_credentials = false;
4410    let method = reqwest::Method::GET;
4411    loop {
4412        let result = list_user_upcoming_billing_invoice_lines_inner(
4413            configuration,
4414            &mut backoff,
4415            user_id.clone(),
4416            page_token.clone(),
4417            page_size.clone(),
4418        )
4419        .await;
4420
4421        match result {
4422            Ok(result) => return Ok(result),
4423            Err(Error::ResponseError(response)) => {
4424                if !refreshed_credentials
4425                    && matches!(
4426                        response.status,
4427                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4428                    )
4429                {
4430                    // Attempt to refresh credentials
4431                    match configuration.qcs_config.refresh().await {
4432                        Ok(_) => {
4433                            refreshed_credentials = true;
4434                            continue;
4435                        }
4436                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4437                            error,
4438                            oauth_session: _,
4439                        }) => {
4440                            // Token refresh succeeded but persistence failed
4441                            // The token is already in memory and will be used for this request
4442                            #[cfg(feature = "tracing")]
4443                            tracing::warn!(
4444                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
4445                                error
4446                            );
4447                            refreshed_credentials = true;
4448                            continue;
4449                        }
4450                        Err(e) => return Err(e.into()),
4451                    }
4452                } else if let Some(duration) = response.retry_delay {
4453                    tokio::time::sleep(duration).await;
4454                    continue;
4455                }
4456
4457                return Err(Error::ResponseError(response));
4458            }
4459            Err(Error::Reqwest(error)) => {
4460                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
4461                    tokio::time::sleep(duration).await;
4462                    continue;
4463                }
4464
4465                return Err(Error::Reqwest(error));
4466            }
4467            Err(Error::Io(error)) => {
4468                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
4469                    tokio::time::sleep(duration).await;
4470                    continue;
4471                }
4472
4473                return Err(Error::Io(error));
4474            }
4475            Err(error) => return Err(error),
4476        }
4477    }
4478}
4479async fn list_viewer_announcements_inner(
4480    configuration: &configuration::Configuration,
4481    backoff: &mut ExponentialBackoff,
4482    page_size: Option<i64>,
4483    page_token: Option<&str>,
4484    include_dismissed: Option<bool>,
4485) -> Result<models::AnnouncementsResponse, Error<ListViewerAnnouncementsError>> {
4486    let local_var_configuration = configuration;
4487    // add a prefix to parameters to efficiently prevent name collisions
4488    let p_query_page_size = page_size;
4489    let p_query_page_token = page_token;
4490    let p_query_include_dismissed = include_dismissed;
4491
4492    let local_var_client = &local_var_configuration.client;
4493
4494    let local_var_uri_str = format!(
4495        "{}/v1/viewer/announcements",
4496        local_var_configuration.qcs_config.api_url()
4497    );
4498    let mut local_var_req_builder =
4499        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
4500
4501    #[cfg(feature = "tracing")]
4502    {
4503        // Ignore parsing errors if the URL is invalid for some reason.
4504        // If it is invalid, it will turn up as an error later when actually making the request.
4505        let local_var_do_tracing = local_var_uri_str
4506            .parse::<::url::Url>()
4507            .ok()
4508            .is_none_or(|url| {
4509                configuration
4510                    .qcs_config
4511                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
4512            });
4513
4514        if local_var_do_tracing {
4515            ::tracing::debug!(
4516                url=%local_var_uri_str,
4517                method="GET",
4518                "making list_viewer_announcements request",
4519            );
4520        }
4521    }
4522
4523    if let Some(ref local_var_str) = p_query_page_size {
4524        local_var_req_builder =
4525            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
4526    }
4527    if let Some(ref local_var_str) = p_query_page_token {
4528        local_var_req_builder =
4529            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
4530    }
4531    if let Some(ref local_var_str) = p_query_include_dismissed {
4532        local_var_req_builder =
4533            local_var_req_builder.query(&[("includeDismissed", &local_var_str.to_string())]);
4534    }
4535
4536    // Use the QCS Bearer token if a client OAuthSession is present,
4537    // but do not require one when the security schema says it is optional.
4538    {
4539        use qcs_api_client_common::configuration::TokenError;
4540
4541        #[allow(
4542            clippy::nonminimal_bool,
4543            clippy::eq_op,
4544            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
4545        )]
4546        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
4547
4548        let token = local_var_configuration
4549            .qcs_config
4550            .get_bearer_access_token()
4551            .await;
4552
4553        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
4554            // the client is configured without any OAuthSession, but this call does not require one.
4555            #[cfg(feature = "tracing")]
4556            tracing::debug!(
4557                "No client credentials found, but this call does not require authentication."
4558            );
4559        } else {
4560            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
4561        }
4562    }
4563
4564    let local_var_req = local_var_req_builder.build()?;
4565    let local_var_resp = local_var_client.execute(local_var_req).await?;
4566
4567    let local_var_status = local_var_resp.status();
4568    let local_var_raw_content_type = local_var_resp
4569        .headers()
4570        .get("content-type")
4571        .and_then(|v| v.to_str().ok())
4572        .unwrap_or("application/octet-stream")
4573        .to_string();
4574    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
4575
4576    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
4577        let local_var_content = local_var_resp.text().await?;
4578        match local_var_content_type {
4579            ContentType::Json => serde_path_to_error::deserialize(
4580                &mut serde_json::Deserializer::from_str(&local_var_content),
4581            )
4582            .map_err(Error::from),
4583            ContentType::Text => Err(Error::InvalidContentType {
4584                content_type: local_var_raw_content_type,
4585                return_type: "models::AnnouncementsResponse",
4586            }),
4587            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
4588                content_type: unknown_type,
4589                return_type: "models::AnnouncementsResponse",
4590            }),
4591        }
4592    } else {
4593        let local_var_retry_delay =
4594            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
4595        let local_var_content = local_var_resp.text().await?;
4596        let local_var_entity: Option<ListViewerAnnouncementsError> =
4597            serde_json::from_str(&local_var_content).ok();
4598        let local_var_error = ResponseContent {
4599            status: local_var_status,
4600            content: local_var_content,
4601            entity: local_var_entity,
4602            retry_delay: local_var_retry_delay,
4603        };
4604        Err(Error::ResponseError(local_var_error))
4605    }
4606}
4607
4608/// List all announcements relevant to the authenticating user. By default, does not include dismissed announcements.
4609pub async fn list_viewer_announcements(
4610    configuration: &configuration::Configuration,
4611    page_size: Option<i64>,
4612    page_token: Option<&str>,
4613    include_dismissed: Option<bool>,
4614) -> Result<models::AnnouncementsResponse, Error<ListViewerAnnouncementsError>> {
4615    let mut backoff = configuration.backoff.clone();
4616    let mut refreshed_credentials = false;
4617    let method = reqwest::Method::GET;
4618    loop {
4619        let result = list_viewer_announcements_inner(
4620            configuration,
4621            &mut backoff,
4622            page_size.clone(),
4623            page_token.clone(),
4624            include_dismissed.clone(),
4625        )
4626        .await;
4627
4628        match result {
4629            Ok(result) => return Ok(result),
4630            Err(Error::ResponseError(response)) => {
4631                if !refreshed_credentials
4632                    && matches!(
4633                        response.status,
4634                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4635                    )
4636                {
4637                    // Attempt to refresh credentials
4638                    match configuration.qcs_config.refresh().await {
4639                        Ok(_) => {
4640                            refreshed_credentials = true;
4641                            continue;
4642                        }
4643                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4644                            error,
4645                            oauth_session: _,
4646                        }) => {
4647                            // Token refresh succeeded but persistence failed
4648                            // The token is already in memory and will be used for this request
4649                            #[cfg(feature = "tracing")]
4650                            tracing::warn!(
4651                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
4652                                error
4653                            );
4654                            refreshed_credentials = true;
4655                            continue;
4656                        }
4657                        Err(e) => return Err(e.into()),
4658                    }
4659                } else if let Some(duration) = response.retry_delay {
4660                    tokio::time::sleep(duration).await;
4661                    continue;
4662                }
4663
4664                return Err(Error::ResponseError(response));
4665            }
4666            Err(Error::Reqwest(error)) => {
4667                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
4668                    tokio::time::sleep(duration).await;
4669                    continue;
4670                }
4671
4672                return Err(Error::Reqwest(error));
4673            }
4674            Err(Error::Io(error)) => {
4675                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
4676                    tokio::time::sleep(duration).await;
4677                    continue;
4678                }
4679
4680                return Err(Error::Io(error));
4681            }
4682            Err(error) => return Err(error),
4683        }
4684    }
4685}
4686async fn put_viewer_user_onboarding_completed_inner(
4687    configuration: &configuration::Configuration,
4688    backoff: &mut ExponentialBackoff,
4689    viewer_user_onboarding_completed: Option<crate::models::ViewerUserOnboardingCompleted>,
4690) -> Result<models::ViewerUserOnboardingCompleted, Error<PutViewerUserOnboardingCompletedError>> {
4691    let local_var_configuration = configuration;
4692    // add a prefix to parameters to efficiently prevent name collisions
4693    let p_body_viewer_user_onboarding_completed = viewer_user_onboarding_completed;
4694
4695    let local_var_client = &local_var_configuration.client;
4696
4697    let local_var_uri_str = format!(
4698        "{}/v1/viewer/onboardingCompleted",
4699        local_var_configuration.qcs_config.api_url()
4700    );
4701    let mut local_var_req_builder =
4702        local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str());
4703
4704    #[cfg(feature = "tracing")]
4705    {
4706        // Ignore parsing errors if the URL is invalid for some reason.
4707        // If it is invalid, it will turn up as an error later when actually making the request.
4708        let local_var_do_tracing = local_var_uri_str
4709            .parse::<::url::Url>()
4710            .ok()
4711            .is_none_or(|url| {
4712                configuration
4713                    .qcs_config
4714                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
4715            });
4716
4717        if local_var_do_tracing {
4718            ::tracing::debug!(
4719                url=%local_var_uri_str,
4720                method="PUT",
4721                "making put_viewer_user_onboarding_completed request",
4722            );
4723        }
4724    }
4725
4726    // Use the QCS Bearer token if a client OAuthSession is present,
4727    // but do not require one when the security schema says it is optional.
4728    {
4729        use qcs_api_client_common::configuration::TokenError;
4730
4731        #[allow(
4732            clippy::nonminimal_bool,
4733            clippy::eq_op,
4734            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
4735        )]
4736        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
4737
4738        let token = local_var_configuration
4739            .qcs_config
4740            .get_bearer_access_token()
4741            .await;
4742
4743        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
4744            // the client is configured without any OAuthSession, but this call does not require one.
4745            #[cfg(feature = "tracing")]
4746            tracing::debug!(
4747                "No client credentials found, but this call does not require authentication."
4748            );
4749        } else {
4750            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
4751        }
4752    }
4753
4754    local_var_req_builder = local_var_req_builder.json(&p_body_viewer_user_onboarding_completed);
4755
4756    let local_var_req = local_var_req_builder.build()?;
4757    let local_var_resp = local_var_client.execute(local_var_req).await?;
4758
4759    let local_var_status = local_var_resp.status();
4760    let local_var_raw_content_type = local_var_resp
4761        .headers()
4762        .get("content-type")
4763        .and_then(|v| v.to_str().ok())
4764        .unwrap_or("application/octet-stream")
4765        .to_string();
4766    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
4767
4768    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
4769        let local_var_content = local_var_resp.text().await?;
4770        match local_var_content_type {
4771            ContentType::Json => serde_path_to_error::deserialize(
4772                &mut serde_json::Deserializer::from_str(&local_var_content),
4773            )
4774            .map_err(Error::from),
4775            ContentType::Text => Err(Error::InvalidContentType {
4776                content_type: local_var_raw_content_type,
4777                return_type: "models::ViewerUserOnboardingCompleted",
4778            }),
4779            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
4780                content_type: unknown_type,
4781                return_type: "models::ViewerUserOnboardingCompleted",
4782            }),
4783        }
4784    } else {
4785        let local_var_retry_delay =
4786            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
4787        let local_var_content = local_var_resp.text().await?;
4788        let local_var_entity: Option<PutViewerUserOnboardingCompletedError> =
4789            serde_json::from_str(&local_var_content).ok();
4790        let local_var_error = ResponseContent {
4791            status: local_var_status,
4792            content: local_var_content,
4793            entity: local_var_entity,
4794            retry_delay: local_var_retry_delay,
4795        };
4796        Err(Error::ResponseError(local_var_error))
4797    }
4798}
4799
4800/// Update the onboarding status of the authenticated user.
4801pub async fn put_viewer_user_onboarding_completed(
4802    configuration: &configuration::Configuration,
4803    viewer_user_onboarding_completed: Option<crate::models::ViewerUserOnboardingCompleted>,
4804) -> Result<models::ViewerUserOnboardingCompleted, Error<PutViewerUserOnboardingCompletedError>> {
4805    let mut backoff = configuration.backoff.clone();
4806    let mut refreshed_credentials = false;
4807    let method = reqwest::Method::PUT;
4808    loop {
4809        let result = put_viewer_user_onboarding_completed_inner(
4810            configuration,
4811            &mut backoff,
4812            viewer_user_onboarding_completed.clone(),
4813        )
4814        .await;
4815
4816        match result {
4817            Ok(result) => return Ok(result),
4818            Err(Error::ResponseError(response)) => {
4819                if !refreshed_credentials
4820                    && matches!(
4821                        response.status,
4822                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4823                    )
4824                {
4825                    // Attempt to refresh credentials
4826                    match configuration.qcs_config.refresh().await {
4827                        Ok(_) => {
4828                            refreshed_credentials = true;
4829                            continue;
4830                        }
4831                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4832                            error,
4833                            oauth_session: _,
4834                        }) => {
4835                            // Token refresh succeeded but persistence failed
4836                            // The token is already in memory and will be used for this request
4837                            #[cfg(feature = "tracing")]
4838                            tracing::warn!(
4839                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
4840                                error
4841                            );
4842                            refreshed_credentials = true;
4843                            continue;
4844                        }
4845                        Err(e) => return Err(e.into()),
4846                    }
4847                } else if let Some(duration) = response.retry_delay {
4848                    tokio::time::sleep(duration).await;
4849                    continue;
4850                }
4851
4852                return Err(Error::ResponseError(response));
4853            }
4854            Err(Error::Reqwest(error)) => {
4855                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
4856                    tokio::time::sleep(duration).await;
4857                    continue;
4858                }
4859
4860                return Err(Error::Reqwest(error));
4861            }
4862            Err(Error::Io(error)) => {
4863                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
4864                    tokio::time::sleep(duration).await;
4865                    continue;
4866                }
4867
4868                return Err(Error::Io(error));
4869            }
4870            Err(error) => return Err(error),
4871        }
4872    }
4873}
4874async fn remove_group_user_inner(
4875    configuration: &configuration::Configuration,
4876    backoff: &mut ExponentialBackoff,
4877    remove_group_user_request: crate::models::RemoveGroupUserRequest,
4878) -> Result<(), Error<RemoveGroupUserError>> {
4879    let local_var_configuration = configuration;
4880    // add a prefix to parameters to efficiently prevent name collisions
4881    let p_body_remove_group_user_request = remove_group_user_request;
4882
4883    let local_var_client = &local_var_configuration.client;
4884
4885    let local_var_uri_str = format!(
4886        "{}/v1/groups:removeUser",
4887        local_var_configuration.qcs_config.api_url()
4888    );
4889    let mut local_var_req_builder =
4890        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
4891
4892    #[cfg(feature = "tracing")]
4893    {
4894        // Ignore parsing errors if the URL is invalid for some reason.
4895        // If it is invalid, it will turn up as an error later when actually making the request.
4896        let local_var_do_tracing = local_var_uri_str
4897            .parse::<::url::Url>()
4898            .ok()
4899            .is_none_or(|url| {
4900                configuration
4901                    .qcs_config
4902                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
4903            });
4904
4905        if local_var_do_tracing {
4906            ::tracing::debug!(
4907                url=%local_var_uri_str,
4908                method="POST",
4909                "making remove_group_user request",
4910            );
4911        }
4912    }
4913
4914    // Use the QCS Bearer token if a client OAuthSession is present,
4915    // but do not require one when the security schema says it is optional.
4916    {
4917        use qcs_api_client_common::configuration::TokenError;
4918
4919        #[allow(
4920            clippy::nonminimal_bool,
4921            clippy::eq_op,
4922            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
4923        )]
4924        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
4925
4926        let token = local_var_configuration
4927            .qcs_config
4928            .get_bearer_access_token()
4929            .await;
4930
4931        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
4932            // the client is configured without any OAuthSession, but this call does not require one.
4933            #[cfg(feature = "tracing")]
4934            tracing::debug!(
4935                "No client credentials found, but this call does not require authentication."
4936            );
4937        } else {
4938            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
4939        }
4940    }
4941
4942    local_var_req_builder = local_var_req_builder.json(&p_body_remove_group_user_request);
4943
4944    let local_var_req = local_var_req_builder.build()?;
4945    let local_var_resp = local_var_client.execute(local_var_req).await?;
4946
4947    let local_var_status = local_var_resp.status();
4948
4949    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
4950        Ok(())
4951    } else {
4952        let local_var_retry_delay =
4953            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
4954        let local_var_content = local_var_resp.text().await?;
4955        let local_var_entity: Option<RemoveGroupUserError> =
4956            serde_json::from_str(&local_var_content).ok();
4957        let local_var_error = ResponseContent {
4958            status: local_var_status,
4959            content: local_var_content,
4960            entity: local_var_entity,
4961            retry_delay: local_var_retry_delay,
4962        };
4963        Err(Error::ResponseError(local_var_error))
4964    }
4965}
4966
4967/// Remove a user from a group. Note, group membership may take several minutes to update within our identity provider. After removing a user from a group, please allow up to 60 minutes for changes to be reflected.
4968pub async fn remove_group_user(
4969    configuration: &configuration::Configuration,
4970    remove_group_user_request: crate::models::RemoveGroupUserRequest,
4971) -> Result<(), Error<RemoveGroupUserError>> {
4972    let mut backoff = configuration.backoff.clone();
4973    let mut refreshed_credentials = false;
4974    let method = reqwest::Method::POST;
4975    loop {
4976        let result = remove_group_user_inner(
4977            configuration,
4978            &mut backoff,
4979            remove_group_user_request.clone(),
4980        )
4981        .await;
4982
4983        match result {
4984            Ok(result) => return Ok(result),
4985            Err(Error::ResponseError(response)) => {
4986                if !refreshed_credentials
4987                    && matches!(
4988                        response.status,
4989                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
4990                    )
4991                {
4992                    // Attempt to refresh credentials
4993                    match configuration.qcs_config.refresh().await {
4994                        Ok(_) => {
4995                            refreshed_credentials = true;
4996                            continue;
4997                        }
4998                        Err(::qcs_api_client_common::configuration::TokenError::Write {
4999                            error,
5000                            oauth_session: _,
5001                        }) => {
5002                            // Token refresh succeeded but persistence failed
5003                            // The token is already in memory and will be used for this request
5004                            #[cfg(feature = "tracing")]
5005                            tracing::warn!(
5006                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
5007                                error
5008                            );
5009                            refreshed_credentials = true;
5010                            continue;
5011                        }
5012                        Err(e) => return Err(e.into()),
5013                    }
5014                } else if let Some(duration) = response.retry_delay {
5015                    tokio::time::sleep(duration).await;
5016                    continue;
5017                }
5018
5019                return Err(Error::ResponseError(response));
5020            }
5021            Err(Error::Reqwest(error)) => {
5022                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
5023                    tokio::time::sleep(duration).await;
5024                    continue;
5025                }
5026
5027                return Err(Error::Reqwest(error));
5028            }
5029            Err(Error::Io(error)) => {
5030                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
5031                    tokio::time::sleep(duration).await;
5032                    continue;
5033                }
5034
5035                return Err(Error::Io(error));
5036            }
5037            Err(error) => return Err(error),
5038        }
5039    }
5040}
5041async fn update_viewer_user_profile_inner(
5042    configuration: &configuration::Configuration,
5043    backoff: &mut ExponentialBackoff,
5044    update_viewer_user_profile_request: crate::models::UpdateViewerUserProfileRequest,
5045) -> Result<models::User, Error<UpdateViewerUserProfileError>> {
5046    let local_var_configuration = configuration;
5047    // add a prefix to parameters to efficiently prevent name collisions
5048    let p_body_update_viewer_user_profile_request = update_viewer_user_profile_request;
5049
5050    let local_var_client = &local_var_configuration.client;
5051
5052    let local_var_uri_str = format!(
5053        "{}/v1/viewer/userProfile",
5054        local_var_configuration.qcs_config.api_url()
5055    );
5056    let mut local_var_req_builder =
5057        local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str());
5058
5059    #[cfg(feature = "tracing")]
5060    {
5061        // Ignore parsing errors if the URL is invalid for some reason.
5062        // If it is invalid, it will turn up as an error later when actually making the request.
5063        let local_var_do_tracing = local_var_uri_str
5064            .parse::<::url::Url>()
5065            .ok()
5066            .is_none_or(|url| {
5067                configuration
5068                    .qcs_config
5069                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
5070            });
5071
5072        if local_var_do_tracing {
5073            ::tracing::debug!(
5074                url=%local_var_uri_str,
5075                method="PUT",
5076                "making update_viewer_user_profile request",
5077            );
5078        }
5079    }
5080
5081    // Use the QCS Bearer token if a client OAuthSession is present,
5082    // but do not require one when the security schema says it is optional.
5083    {
5084        use qcs_api_client_common::configuration::TokenError;
5085
5086        #[allow(
5087            clippy::nonminimal_bool,
5088            clippy::eq_op,
5089            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
5090        )]
5091        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
5092
5093        let token = local_var_configuration
5094            .qcs_config
5095            .get_bearer_access_token()
5096            .await;
5097
5098        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
5099            // the client is configured without any OAuthSession, but this call does not require one.
5100            #[cfg(feature = "tracing")]
5101            tracing::debug!(
5102                "No client credentials found, but this call does not require authentication."
5103            );
5104        } else {
5105            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
5106        }
5107    }
5108
5109    local_var_req_builder = local_var_req_builder.json(&p_body_update_viewer_user_profile_request);
5110
5111    let local_var_req = local_var_req_builder.build()?;
5112    let local_var_resp = local_var_client.execute(local_var_req).await?;
5113
5114    let local_var_status = local_var_resp.status();
5115    let local_var_raw_content_type = local_var_resp
5116        .headers()
5117        .get("content-type")
5118        .and_then(|v| v.to_str().ok())
5119        .unwrap_or("application/octet-stream")
5120        .to_string();
5121    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
5122
5123    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
5124        let local_var_content = local_var_resp.text().await?;
5125        match local_var_content_type {
5126            ContentType::Json => serde_path_to_error::deserialize(
5127                &mut serde_json::Deserializer::from_str(&local_var_content),
5128            )
5129            .map_err(Error::from),
5130            ContentType::Text => Err(Error::InvalidContentType {
5131                content_type: local_var_raw_content_type,
5132                return_type: "models::User",
5133            }),
5134            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
5135                content_type: unknown_type,
5136                return_type: "models::User",
5137            }),
5138        }
5139    } else {
5140        let local_var_retry_delay =
5141            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
5142        let local_var_content = local_var_resp.text().await?;
5143        let local_var_entity: Option<UpdateViewerUserProfileError> =
5144            serde_json::from_str(&local_var_content).ok();
5145        let local_var_error = ResponseContent {
5146            status: local_var_status,
5147            content: local_var_content,
5148            entity: local_var_entity,
5149            retry_delay: local_var_retry_delay,
5150        };
5151        Err(Error::ResponseError(local_var_error))
5152    }
5153}
5154
5155/// Update the profile of the authenticated user.
5156pub async fn update_viewer_user_profile(
5157    configuration: &configuration::Configuration,
5158    update_viewer_user_profile_request: crate::models::UpdateViewerUserProfileRequest,
5159) -> Result<models::User, Error<UpdateViewerUserProfileError>> {
5160    let mut backoff = configuration.backoff.clone();
5161    let mut refreshed_credentials = false;
5162    let method = reqwest::Method::PUT;
5163    loop {
5164        let result = update_viewer_user_profile_inner(
5165            configuration,
5166            &mut backoff,
5167            update_viewer_user_profile_request.clone(),
5168        )
5169        .await;
5170
5171        match result {
5172            Ok(result) => return Ok(result),
5173            Err(Error::ResponseError(response)) => {
5174                if !refreshed_credentials
5175                    && matches!(
5176                        response.status,
5177                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
5178                    )
5179                {
5180                    // Attempt to refresh credentials
5181                    match configuration.qcs_config.refresh().await {
5182                        Ok(_) => {
5183                            refreshed_credentials = true;
5184                            continue;
5185                        }
5186                        Err(::qcs_api_client_common::configuration::TokenError::Write {
5187                            error,
5188                            oauth_session: _,
5189                        }) => {
5190                            // Token refresh succeeded but persistence failed
5191                            // The token is already in memory and will be used for this request
5192                            #[cfg(feature = "tracing")]
5193                            tracing::warn!(
5194                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
5195                                error
5196                            );
5197                            refreshed_credentials = true;
5198                            continue;
5199                        }
5200                        Err(e) => return Err(e.into()),
5201                    }
5202                } else if let Some(duration) = response.retry_delay {
5203                    tokio::time::sleep(duration).await;
5204                    continue;
5205                }
5206
5207                return Err(Error::ResponseError(response));
5208            }
5209            Err(Error::Reqwest(error)) => {
5210                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
5211                    tokio::time::sleep(duration).await;
5212                    continue;
5213                }
5214
5215                return Err(Error::Reqwest(error));
5216            }
5217            Err(Error::Io(error)) => {
5218                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
5219                    tokio::time::sleep(duration).await;
5220                    continue;
5221                }
5222
5223                return Err(Error::Io(error));
5224            }
5225            Err(error) => return Err(error),
5226        }
5227    }
5228}