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