qcs_api_client_openapi/apis/
reservations_api.rs

1// Copyright 2022 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::{configuration, Error};
26use crate::apis::ResponseContent;
27use ::qcs_api_client_common::backoff::{
28    duration_from_io_error, duration_from_reqwest_error, duration_from_response, ExponentialBackoff,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::TokenRefresher;
32use reqwest::StatusCode;
33use serde::{Deserialize, Serialize};
34
35/// struct for typed errors of method [`create_reservation`]
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(untagged)]
38pub enum CreateReservationError {
39    Status401(crate::models::Error),
40    Status402(crate::models::Error),
41    Status403(crate::models::Error),
42    Status409(crate::models::Error),
43    Status422(crate::models::Error),
44    UnknownValue(serde_json::Value),
45}
46
47/// struct for typed errors of method [`delete_reservation`]
48#[derive(Debug, Clone, Serialize, Deserialize)]
49#[serde(untagged)]
50pub enum DeleteReservationError {
51    Status401(crate::models::Error),
52    Status403(crate::models::Error),
53    Status404(crate::models::Error),
54    UnknownValue(serde_json::Value),
55}
56
57/// struct for typed errors of method [`find_available_reservations`]
58#[derive(Debug, Clone, Serialize, Deserialize)]
59#[serde(untagged)]
60pub enum FindAvailableReservationsError {
61    Status401(crate::models::Error),
62    Status422(crate::models::Error),
63    UnknownValue(serde_json::Value),
64}
65
66/// struct for typed errors of method [`get_quantum_processor_calendar`]
67#[derive(Debug, Clone, Serialize, Deserialize)]
68#[serde(untagged)]
69pub enum GetQuantumProcessorCalendarError {
70    Status403(crate::models::Error),
71    Status404(crate::models::Error),
72    UnknownValue(serde_json::Value),
73}
74
75/// struct for typed errors of method [`list_group_reservations`]
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(untagged)]
78pub enum ListGroupReservationsError {
79    Status401(crate::models::Error),
80    Status422(crate::models::Error),
81    UnknownValue(serde_json::Value),
82}
83
84/// struct for typed errors of method [`list_reservations`]
85#[derive(Debug, Clone, Serialize, Deserialize)]
86#[serde(untagged)]
87pub enum ListReservationsError {
88    Status401(crate::models::Error),
89    Status422(crate::models::Error),
90    UnknownValue(serde_json::Value),
91}
92
93async fn create_reservation_inner(
94    configuration: &configuration::Configuration,
95    backoff: &mut ExponentialBackoff,
96    create_reservation_request: crate::models::CreateReservationRequest,
97    x_qcs_account_id: Option<&str>,
98    x_qcs_account_type: Option<crate::models::AccountType>,
99) -> Result<crate::models::Reservation, Error<CreateReservationError>> {
100    let local_var_configuration = configuration;
101
102    let local_var_client = &local_var_configuration.client;
103
104    let local_var_uri_str = format!(
105        "{}/v1/reservations",
106        local_var_configuration.qcs_config.api_url()
107    );
108    let mut local_var_req_builder =
109        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
110
111    #[cfg(feature = "tracing")]
112    {
113        // Ignore parsing errors if the URL is invalid for some reason.
114        // If it is invalid, it will turn up as an error later when actually making the request.
115        let local_var_do_tracing =
116            local_var_uri_str
117                .parse::<::url::Url>()
118                .ok()
119                .map_or(true, |url| {
120                    configuration
121                        .qcs_config
122                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
123                });
124
125        if local_var_do_tracing {
126            ::tracing::debug!(
127                url=%local_var_uri_str,
128                method="POST",
129                "making create_reservation request",
130            );
131        }
132    }
133
134    if let Some(local_var_param_value) = x_qcs_account_id {
135        local_var_req_builder =
136            local_var_req_builder.header("x-qcs-account-id", local_var_param_value.to_string());
137    }
138    if let Some(local_var_param_value) = x_qcs_account_type {
139        local_var_req_builder =
140            local_var_req_builder.header("x-qcs-account-type", local_var_param_value.to_string());
141    }
142
143    // Use the QCS Bearer token if a client OAuthSession is present,
144    // but do not require one when the security schema says it is optional.
145    {
146        use qcs_api_client_common::configuration::TokenError;
147
148        #[allow(
149            clippy::nonminimal_bool,
150            clippy::eq_op,
151            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
152        )]
153        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
154
155        let token = local_var_configuration
156            .qcs_config
157            .get_bearer_access_token()
158            .await;
159
160        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
161            // the client is configured without any OAuthSession, but this call does not require one.
162            #[cfg(feature = "tracing")]
163            tracing::debug!(
164                "No client credentials found, but this call does not require authentication."
165            );
166        } else {
167            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
168        }
169    }
170
171    local_var_req_builder = local_var_req_builder.json(&create_reservation_request);
172
173    let local_var_req = local_var_req_builder.build()?;
174    let local_var_resp = local_var_client.execute(local_var_req).await?;
175
176    let local_var_status = local_var_resp.status();
177
178    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
179        let local_var_content = local_var_resp.text().await?;
180        serde_json::from_str(&local_var_content).map_err(Error::from)
181    } else {
182        let local_var_retry_delay =
183            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
184        let local_var_content = local_var_resp.text().await?;
185        let local_var_entity: Option<CreateReservationError> =
186            serde_json::from_str(&local_var_content).ok();
187        let local_var_error = ResponseContent {
188            status: local_var_status,
189            content: local_var_content,
190            entity: local_var_entity,
191            retry_delay: local_var_retry_delay,
192        };
193        Err(Error::ResponseError(local_var_error))
194    }
195}
196
197/// Create a new reservation.  The following precedence applies when specifying the reservation subject account ID and type: * request body `accountId` field, or if unset then `X-QCS-ACCOUNT-ID` header, or if unset then requesting user's ID. * request body `accountType` field, or if unset then `X-QCS-ACCOUNT-TYPE` header, or if unset then \"user\" type.
198pub async fn create_reservation(
199    configuration: &configuration::Configuration,
200    create_reservation_request: crate::models::CreateReservationRequest,
201    x_qcs_account_id: Option<&str>,
202    x_qcs_account_type: Option<crate::models::AccountType>,
203) -> Result<crate::models::Reservation, Error<CreateReservationError>> {
204    let mut backoff = configuration.backoff.clone();
205    let mut refreshed_credentials = false;
206    let method = reqwest::Method::POST;
207    loop {
208        let result = create_reservation_inner(
209            configuration,
210            &mut backoff,
211            create_reservation_request.clone(),
212            x_qcs_account_id.clone(),
213            x_qcs_account_type.clone(),
214        )
215        .await;
216
217        match result {
218            Ok(result) => return Ok(result),
219            Err(Error::ResponseError(response)) => {
220                if !refreshed_credentials
221                    && matches!(
222                        response.status,
223                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
224                    )
225                {
226                    configuration.qcs_config.refresh().await?;
227                    refreshed_credentials = true;
228                    continue;
229                } else if let Some(duration) = response.retry_delay {
230                    tokio::time::sleep(duration).await;
231                    continue;
232                }
233
234                return Err(Error::ResponseError(response));
235            }
236            Err(Error::Reqwest(error)) => {
237                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
238                    tokio::time::sleep(duration).await;
239                    continue;
240                }
241
242                return Err(Error::Reqwest(error));
243            }
244            Err(Error::Io(error)) => {
245                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
246                    tokio::time::sleep(duration).await;
247                    continue;
248                }
249
250                return Err(Error::Io(error));
251            }
252            Err(error) => return Err(error),
253        }
254    }
255}
256async fn delete_reservation_inner(
257    configuration: &configuration::Configuration,
258    backoff: &mut ExponentialBackoff,
259    reservation_id: i64,
260) -> Result<crate::models::Reservation, Error<DeleteReservationError>> {
261    let local_var_configuration = configuration;
262
263    let local_var_client = &local_var_configuration.client;
264
265    let local_var_uri_str = format!(
266        "{}/v1/reservations/{reservationId}",
267        local_var_configuration.qcs_config.api_url(),
268        reservationId = reservation_id
269    );
270    let mut local_var_req_builder =
271        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
272
273    #[cfg(feature = "tracing")]
274    {
275        // Ignore parsing errors if the URL is invalid for some reason.
276        // If it is invalid, it will turn up as an error later when actually making the request.
277        let local_var_do_tracing =
278            local_var_uri_str
279                .parse::<::url::Url>()
280                .ok()
281                .map_or(true, |url| {
282                    configuration
283                        .qcs_config
284                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
285                });
286
287        if local_var_do_tracing {
288            ::tracing::debug!(
289                url=%local_var_uri_str,
290                method="DELETE",
291                "making delete_reservation request",
292            );
293        }
294    }
295
296    // Use the QCS Bearer token if a client OAuthSession is present,
297    // but do not require one when the security schema says it is optional.
298    {
299        use qcs_api_client_common::configuration::TokenError;
300
301        #[allow(
302            clippy::nonminimal_bool,
303            clippy::eq_op,
304            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
305        )]
306        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
307
308        let token = local_var_configuration
309            .qcs_config
310            .get_bearer_access_token()
311            .await;
312
313        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
314            // the client is configured without any OAuthSession, but this call does not require one.
315            #[cfg(feature = "tracing")]
316            tracing::debug!(
317                "No client credentials found, but this call does not require authentication."
318            );
319        } else {
320            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
321        }
322    }
323
324    let local_var_req = local_var_req_builder.build()?;
325    let local_var_resp = local_var_client.execute(local_var_req).await?;
326
327    let local_var_status = local_var_resp.status();
328
329    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
330        let local_var_content = local_var_resp.text().await?;
331        serde_json::from_str(&local_var_content).map_err(Error::from)
332    } else {
333        let local_var_retry_delay =
334            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
335        let local_var_content = local_var_resp.text().await?;
336        let local_var_entity: Option<DeleteReservationError> =
337            serde_json::from_str(&local_var_content).ok();
338        let local_var_error = ResponseContent {
339            status: local_var_status,
340            content: local_var_content,
341            entity: local_var_entity,
342            retry_delay: local_var_retry_delay,
343        };
344        Err(Error::ResponseError(local_var_error))
345    }
346}
347
348/// Cancel an existing reservation for the user.
349pub async fn delete_reservation(
350    configuration: &configuration::Configuration,
351    reservation_id: i64,
352) -> Result<crate::models::Reservation, Error<DeleteReservationError>> {
353    let mut backoff = configuration.backoff.clone();
354    let mut refreshed_credentials = false;
355    let method = reqwest::Method::DELETE;
356    loop {
357        let result =
358            delete_reservation_inner(configuration, &mut backoff, reservation_id.clone()).await;
359
360        match result {
361            Ok(result) => return Ok(result),
362            Err(Error::ResponseError(response)) => {
363                if !refreshed_credentials
364                    && matches!(
365                        response.status,
366                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
367                    )
368                {
369                    configuration.qcs_config.refresh().await?;
370                    refreshed_credentials = true;
371                    continue;
372                } else if let Some(duration) = response.retry_delay {
373                    tokio::time::sleep(duration).await;
374                    continue;
375                }
376
377                return Err(Error::ResponseError(response));
378            }
379            Err(Error::Reqwest(error)) => {
380                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
381                    tokio::time::sleep(duration).await;
382                    continue;
383                }
384
385                return Err(Error::Reqwest(error));
386            }
387            Err(Error::Io(error)) => {
388                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
389                    tokio::time::sleep(duration).await;
390                    continue;
391                }
392
393                return Err(Error::Io(error));
394            }
395            Err(error) => return Err(error),
396        }
397    }
398}
399async fn find_available_reservations_inner(
400    configuration: &configuration::Configuration,
401    backoff: &mut ExponentialBackoff,
402    quantum_processor_id: &str,
403    start_time_from: String,
404    duration: &str,
405    page_size: Option<i64>,
406    page_token: Option<&str>,
407) -> Result<crate::models::FindAvailableReservationsResponse, Error<FindAvailableReservationsError>>
408{
409    let local_var_configuration = configuration;
410
411    let local_var_client = &local_var_configuration.client;
412
413    let local_var_uri_str = format!(
414        "{}/v1/reservations:findAvailable",
415        local_var_configuration.qcs_config.api_url()
416    );
417    let mut local_var_req_builder =
418        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
419
420    #[cfg(feature = "tracing")]
421    {
422        // Ignore parsing errors if the URL is invalid for some reason.
423        // If it is invalid, it will turn up as an error later when actually making the request.
424        let local_var_do_tracing =
425            local_var_uri_str
426                .parse::<::url::Url>()
427                .ok()
428                .map_or(true, |url| {
429                    configuration
430                        .qcs_config
431                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
432                });
433
434        if local_var_do_tracing {
435            ::tracing::debug!(
436                url=%local_var_uri_str,
437                method="GET",
438                "making find_available_reservations request",
439            );
440        }
441    }
442
443    if let Some(ref local_var_str) = page_size {
444        local_var_req_builder =
445            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
446    }
447    if let Some(ref local_var_str) = page_token {
448        local_var_req_builder =
449            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
450    }
451    local_var_req_builder =
452        local_var_req_builder.query(&[("quantumProcessorId", &quantum_processor_id.to_string())]);
453    local_var_req_builder =
454        local_var_req_builder.query(&[("startTimeFrom", &start_time_from.to_string())]);
455    local_var_req_builder = local_var_req_builder.query(&[("duration", &duration.to_string())]);
456
457    // Use the QCS Bearer token if a client OAuthSession is present,
458    // but do not require one when the security schema says it is optional.
459    {
460        use qcs_api_client_common::configuration::TokenError;
461
462        #[allow(
463            clippy::nonminimal_bool,
464            clippy::eq_op,
465            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
466        )]
467        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
468
469        let token = local_var_configuration
470            .qcs_config
471            .get_bearer_access_token()
472            .await;
473
474        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
475            // the client is configured without any OAuthSession, but this call does not require one.
476            #[cfg(feature = "tracing")]
477            tracing::debug!(
478                "No client credentials found, but this call does not require authentication."
479            );
480        } else {
481            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
482        }
483    }
484
485    let local_var_req = local_var_req_builder.build()?;
486    let local_var_resp = local_var_client.execute(local_var_req).await?;
487
488    let local_var_status = local_var_resp.status();
489
490    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
491        let local_var_content = local_var_resp.text().await?;
492        serde_json::from_str(&local_var_content).map_err(Error::from)
493    } else {
494        let local_var_retry_delay =
495            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
496        let local_var_content = local_var_resp.text().await?;
497        let local_var_entity: Option<FindAvailableReservationsError> =
498            serde_json::from_str(&local_var_content).ok();
499        let local_var_error = ResponseContent {
500            status: local_var_status,
501            content: local_var_content,
502            entity: local_var_entity,
503            retry_delay: local_var_retry_delay,
504        };
505        Err(Error::ResponseError(local_var_error))
506    }
507}
508
509/// List currently available reservations on the requested Rigetti quantum computer.
510pub async fn find_available_reservations(
511    configuration: &configuration::Configuration,
512    quantum_processor_id: &str,
513    start_time_from: String,
514    duration: &str,
515    page_size: Option<i64>,
516    page_token: Option<&str>,
517) -> Result<crate::models::FindAvailableReservationsResponse, Error<FindAvailableReservationsError>>
518{
519    let mut backoff = configuration.backoff.clone();
520    let mut refreshed_credentials = false;
521    let method = reqwest::Method::GET;
522    loop {
523        let result = find_available_reservations_inner(
524            configuration,
525            &mut backoff,
526            quantum_processor_id.clone(),
527            start_time_from.clone(),
528            duration.clone(),
529            page_size.clone(),
530            page_token.clone(),
531        )
532        .await;
533
534        match result {
535            Ok(result) => return Ok(result),
536            Err(Error::ResponseError(response)) => {
537                if !refreshed_credentials
538                    && matches!(
539                        response.status,
540                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
541                    )
542                {
543                    configuration.qcs_config.refresh().await?;
544                    refreshed_credentials = true;
545                    continue;
546                } else if let Some(duration) = response.retry_delay {
547                    tokio::time::sleep(duration).await;
548                    continue;
549                }
550
551                return Err(Error::ResponseError(response));
552            }
553            Err(Error::Reqwest(error)) => {
554                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
555                    tokio::time::sleep(duration).await;
556                    continue;
557                }
558
559                return Err(Error::Reqwest(error));
560            }
561            Err(Error::Io(error)) => {
562                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
563                    tokio::time::sleep(duration).await;
564                    continue;
565                }
566
567                return Err(Error::Io(error));
568            }
569            Err(error) => return Err(error),
570        }
571    }
572}
573async fn get_quantum_processor_calendar_inner(
574    configuration: &configuration::Configuration,
575    backoff: &mut ExponentialBackoff,
576    quantum_processor_id: &str,
577) -> Result<crate::models::QuantumProcessorCalendar, Error<GetQuantumProcessorCalendarError>> {
578    let local_var_configuration = configuration;
579
580    let local_var_client = &local_var_configuration.client;
581
582    let local_var_uri_str = format!(
583        "{}/v1/calendars/{quantumProcessorId}",
584        local_var_configuration.qcs_config.api_url(),
585        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
586    );
587    let mut local_var_req_builder =
588        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
589
590    #[cfg(feature = "tracing")]
591    {
592        // Ignore parsing errors if the URL is invalid for some reason.
593        // If it is invalid, it will turn up as an error later when actually making the request.
594        let local_var_do_tracing =
595            local_var_uri_str
596                .parse::<::url::Url>()
597                .ok()
598                .map_or(true, |url| {
599                    configuration
600                        .qcs_config
601                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
602                });
603
604        if local_var_do_tracing {
605            ::tracing::debug!(
606                url=%local_var_uri_str,
607                method="GET",
608                "making get_quantum_processor_calendar request",
609            );
610        }
611    }
612
613    // Use the QCS Bearer token if a client OAuthSession is present,
614    // but do not require one when the security schema says it is optional.
615    {
616        use qcs_api_client_common::configuration::TokenError;
617
618        #[allow(
619            clippy::nonminimal_bool,
620            clippy::eq_op,
621            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
622        )]
623        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
624
625        let token = local_var_configuration
626            .qcs_config
627            .get_bearer_access_token()
628            .await;
629
630        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
631            // the client is configured without any OAuthSession, but this call does not require one.
632            #[cfg(feature = "tracing")]
633            tracing::debug!(
634                "No client credentials found, but this call does not require authentication."
635            );
636        } else {
637            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
638        }
639    }
640
641    let local_var_req = local_var_req_builder.build()?;
642    let local_var_resp = local_var_client.execute(local_var_req).await?;
643
644    let local_var_status = local_var_resp.status();
645
646    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
647        let local_var_content = local_var_resp.text().await?;
648        serde_json::from_str(&local_var_content).map_err(Error::from)
649    } else {
650        let local_var_retry_delay =
651            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
652        let local_var_content = local_var_resp.text().await?;
653        let local_var_entity: Option<GetQuantumProcessorCalendarError> =
654            serde_json::from_str(&local_var_content).ok();
655        let local_var_error = ResponseContent {
656            status: local_var_status,
657            content: local_var_content,
658            entity: local_var_entity,
659            retry_delay: local_var_retry_delay,
660        };
661        Err(Error::ResponseError(local_var_error))
662    }
663}
664
665/// Get calendar details for the requested quantum processor.
666pub async fn get_quantum_processor_calendar(
667    configuration: &configuration::Configuration,
668    quantum_processor_id: &str,
669) -> Result<crate::models::QuantumProcessorCalendar, Error<GetQuantumProcessorCalendarError>> {
670    let mut backoff = configuration.backoff.clone();
671    let mut refreshed_credentials = false;
672    let method = reqwest::Method::GET;
673    loop {
674        let result = get_quantum_processor_calendar_inner(
675            configuration,
676            &mut backoff,
677            quantum_processor_id.clone(),
678        )
679        .await;
680
681        match result {
682            Ok(result) => return Ok(result),
683            Err(Error::ResponseError(response)) => {
684                if !refreshed_credentials
685                    && matches!(
686                        response.status,
687                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
688                    )
689                {
690                    configuration.qcs_config.refresh().await?;
691                    refreshed_credentials = true;
692                    continue;
693                } else if let Some(duration) = response.retry_delay {
694                    tokio::time::sleep(duration).await;
695                    continue;
696                }
697
698                return Err(Error::ResponseError(response));
699            }
700            Err(Error::Reqwest(error)) => {
701                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
702                    tokio::time::sleep(duration).await;
703                    continue;
704                }
705
706                return Err(Error::Reqwest(error));
707            }
708            Err(Error::Io(error)) => {
709                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
710                    tokio::time::sleep(duration).await;
711                    continue;
712                }
713
714                return Err(Error::Io(error));
715            }
716            Err(error) => return Err(error),
717        }
718    }
719}
720async fn list_group_reservations_inner(
721    configuration: &configuration::Configuration,
722    backoff: &mut ExponentialBackoff,
723    group_name: &str,
724    filter: Option<&str>,
725    order: Option<&str>,
726    page_size: Option<i64>,
727    page_token: Option<&str>,
728    show_deleted: Option<&str>,
729) -> Result<crate::models::ListReservationsResponse, Error<ListGroupReservationsError>> {
730    let local_var_configuration = configuration;
731
732    let local_var_client = &local_var_configuration.client;
733
734    let local_var_uri_str = format!(
735        "{}/v1/groups/{groupName}/reservations",
736        local_var_configuration.qcs_config.api_url(),
737        groupName = crate::apis::urlencode(group_name)
738    );
739    let mut local_var_req_builder =
740        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
741
742    #[cfg(feature = "tracing")]
743    {
744        // Ignore parsing errors if the URL is invalid for some reason.
745        // If it is invalid, it will turn up as an error later when actually making the request.
746        let local_var_do_tracing =
747            local_var_uri_str
748                .parse::<::url::Url>()
749                .ok()
750                .map_or(true, |url| {
751                    configuration
752                        .qcs_config
753                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
754                });
755
756        if local_var_do_tracing {
757            ::tracing::debug!(
758                url=%local_var_uri_str,
759                method="GET",
760                "making list_group_reservations request",
761            );
762        }
763    }
764
765    if let Some(ref local_var_str) = filter {
766        local_var_req_builder =
767            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
768    }
769    if let Some(ref local_var_str) = order {
770        local_var_req_builder =
771            local_var_req_builder.query(&[("order", &local_var_str.to_string())]);
772    }
773    if let Some(ref local_var_str) = page_size {
774        local_var_req_builder =
775            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
776    }
777    if let Some(ref local_var_str) = page_token {
778        local_var_req_builder =
779            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
780    }
781    if let Some(ref local_var_str) = show_deleted {
782        local_var_req_builder =
783            local_var_req_builder.query(&[("showDeleted", &local_var_str.to_string())]);
784    }
785
786    // Use the QCS Bearer token if a client OAuthSession is present,
787    // but do not require one when the security schema says it is optional.
788    {
789        use qcs_api_client_common::configuration::TokenError;
790
791        #[allow(
792            clippy::nonminimal_bool,
793            clippy::eq_op,
794            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
795        )]
796        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
797
798        let token = local_var_configuration
799            .qcs_config
800            .get_bearer_access_token()
801            .await;
802
803        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
804            // the client is configured without any OAuthSession, but this call does not require one.
805            #[cfg(feature = "tracing")]
806            tracing::debug!(
807                "No client credentials found, but this call does not require authentication."
808            );
809        } else {
810            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
811        }
812    }
813
814    let local_var_req = local_var_req_builder.build()?;
815    let local_var_resp = local_var_client.execute(local_var_req).await?;
816
817    let local_var_status = local_var_resp.status();
818
819    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
820        let local_var_content = local_var_resp.text().await?;
821        serde_json::from_str(&local_var_content).map_err(Error::from)
822    } else {
823        let local_var_retry_delay =
824            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
825        let local_var_content = local_var_resp.text().await?;
826        let local_var_entity: Option<ListGroupReservationsError> =
827            serde_json::from_str(&local_var_content).ok();
828        let local_var_error = ResponseContent {
829            status: local_var_status,
830            content: local_var_content,
831            entity: local_var_entity,
832            retry_delay: local_var_retry_delay,
833        };
834        Err(Error::ResponseError(local_var_error))
835    }
836}
837
838/// List existing reservations for the requested group.  Available filter fields include:  * `startTime` - timestamp * `endTime` - timestamp * `createdTime` - timestamp * `price` - integer * `quantumProcessorId` - string  Available order fields include:  * `startTime` - timestamp * `endTime` - timestamp * `createdTime` - timestamp * `price` - integer
839pub async fn list_group_reservations(
840    configuration: &configuration::Configuration,
841    group_name: &str,
842    filter: Option<&str>,
843    order: Option<&str>,
844    page_size: Option<i64>,
845    page_token: Option<&str>,
846    show_deleted: Option<&str>,
847) -> Result<crate::models::ListReservationsResponse, Error<ListGroupReservationsError>> {
848    let mut backoff = configuration.backoff.clone();
849    let mut refreshed_credentials = false;
850    let method = reqwest::Method::GET;
851    loop {
852        let result = list_group_reservations_inner(
853            configuration,
854            &mut backoff,
855            group_name.clone(),
856            filter.clone(),
857            order.clone(),
858            page_size.clone(),
859            page_token.clone(),
860            show_deleted.clone(),
861        )
862        .await;
863
864        match result {
865            Ok(result) => return Ok(result),
866            Err(Error::ResponseError(response)) => {
867                if !refreshed_credentials
868                    && matches!(
869                        response.status,
870                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
871                    )
872                {
873                    configuration.qcs_config.refresh().await?;
874                    refreshed_credentials = true;
875                    continue;
876                } else if let Some(duration) = response.retry_delay {
877                    tokio::time::sleep(duration).await;
878                    continue;
879                }
880
881                return Err(Error::ResponseError(response));
882            }
883            Err(Error::Reqwest(error)) => {
884                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
885                    tokio::time::sleep(duration).await;
886                    continue;
887                }
888
889                return Err(Error::Reqwest(error));
890            }
891            Err(Error::Io(error)) => {
892                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
893                    tokio::time::sleep(duration).await;
894                    continue;
895                }
896
897                return Err(Error::Io(error));
898            }
899            Err(error) => return Err(error),
900        }
901    }
902}
903async fn list_reservations_inner(
904    configuration: &configuration::Configuration,
905    backoff: &mut ExponentialBackoff,
906    filter: Option<&str>,
907    order: Option<&str>,
908    page_size: Option<i64>,
909    page_token: Option<&str>,
910    show_deleted: Option<&str>,
911    x_qcs_account_id: Option<&str>,
912    x_qcs_account_type: Option<crate::models::AccountType>,
913) -> Result<crate::models::ListReservationsResponse, Error<ListReservationsError>> {
914    let local_var_configuration = configuration;
915
916    let local_var_client = &local_var_configuration.client;
917
918    let local_var_uri_str = format!(
919        "{}/v1/reservations",
920        local_var_configuration.qcs_config.api_url()
921    );
922    let mut local_var_req_builder =
923        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
924
925    #[cfg(feature = "tracing")]
926    {
927        // Ignore parsing errors if the URL is invalid for some reason.
928        // If it is invalid, it will turn up as an error later when actually making the request.
929        let local_var_do_tracing =
930            local_var_uri_str
931                .parse::<::url::Url>()
932                .ok()
933                .map_or(true, |url| {
934                    configuration
935                        .qcs_config
936                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
937                });
938
939        if local_var_do_tracing {
940            ::tracing::debug!(
941                url=%local_var_uri_str,
942                method="GET",
943                "making list_reservations request",
944            );
945        }
946    }
947
948    if let Some(ref local_var_str) = filter {
949        local_var_req_builder =
950            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
951    }
952    if let Some(ref local_var_str) = order {
953        local_var_req_builder =
954            local_var_req_builder.query(&[("order", &local_var_str.to_string())]);
955    }
956    if let Some(ref local_var_str) = page_size {
957        local_var_req_builder =
958            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
959    }
960    if let Some(ref local_var_str) = page_token {
961        local_var_req_builder =
962            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
963    }
964    if let Some(ref local_var_str) = show_deleted {
965        local_var_req_builder =
966            local_var_req_builder.query(&[("showDeleted", &local_var_str.to_string())]);
967    }
968    if let Some(local_var_param_value) = x_qcs_account_id {
969        local_var_req_builder =
970            local_var_req_builder.header("x-qcs-account-id", local_var_param_value.to_string());
971    }
972    if let Some(local_var_param_value) = x_qcs_account_type {
973        local_var_req_builder =
974            local_var_req_builder.header("x-qcs-account-type", local_var_param_value.to_string());
975    }
976
977    // Use the QCS Bearer token if a client OAuthSession is present,
978    // but do not require one when the security schema says it is optional.
979    {
980        use qcs_api_client_common::configuration::TokenError;
981
982        #[allow(
983            clippy::nonminimal_bool,
984            clippy::eq_op,
985            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
986        )]
987        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
988
989        let token = local_var_configuration
990            .qcs_config
991            .get_bearer_access_token()
992            .await;
993
994        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
995            // the client is configured without any OAuthSession, but this call does not require one.
996            #[cfg(feature = "tracing")]
997            tracing::debug!(
998                "No client credentials found, but this call does not require authentication."
999            );
1000        } else {
1001            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
1002        }
1003    }
1004
1005    let local_var_req = local_var_req_builder.build()?;
1006    let local_var_resp = local_var_client.execute(local_var_req).await?;
1007
1008    let local_var_status = local_var_resp.status();
1009
1010    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1011        let local_var_content = local_var_resp.text().await?;
1012        serde_json::from_str(&local_var_content).map_err(Error::from)
1013    } else {
1014        let local_var_retry_delay =
1015            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1016        let local_var_content = local_var_resp.text().await?;
1017        let local_var_entity: Option<ListReservationsError> =
1018            serde_json::from_str(&local_var_content).ok();
1019        let local_var_error = ResponseContent {
1020            status: local_var_status,
1021            content: local_var_content,
1022            entity: local_var_entity,
1023            retry_delay: local_var_retry_delay,
1024        };
1025        Err(Error::ResponseError(local_var_error))
1026    }
1027}
1028
1029/// List existing reservations for the authenticated user, or a target user when specifying `X-QCS-ACCOUNT-ID` and `X-QCS-ACCOUNT-TYPE` headers.  Available filter fields include:  * `startTime` - timestamp * `endTime` - timestamp * `createdTime` - timestamp * `price` - integer * `cancelled` - boolean (deprecated, use `showDeleted` parameter) * `quantumProcessorId` - string  Available order fields include:  * `startTime` - timestamp * `endTime` - timestamp * `createdTime` - timestamp * `price` - integer
1030pub async fn list_reservations(
1031    configuration: &configuration::Configuration,
1032    filter: Option<&str>,
1033    order: Option<&str>,
1034    page_size: Option<i64>,
1035    page_token: Option<&str>,
1036    show_deleted: Option<&str>,
1037    x_qcs_account_id: Option<&str>,
1038    x_qcs_account_type: Option<crate::models::AccountType>,
1039) -> Result<crate::models::ListReservationsResponse, Error<ListReservationsError>> {
1040    let mut backoff = configuration.backoff.clone();
1041    let mut refreshed_credentials = false;
1042    let method = reqwest::Method::GET;
1043    loop {
1044        let result = list_reservations_inner(
1045            configuration,
1046            &mut backoff,
1047            filter.clone(),
1048            order.clone(),
1049            page_size.clone(),
1050            page_token.clone(),
1051            show_deleted.clone(),
1052            x_qcs_account_id.clone(),
1053            x_qcs_account_type.clone(),
1054        )
1055        .await;
1056
1057        match result {
1058            Ok(result) => return Ok(result),
1059            Err(Error::ResponseError(response)) => {
1060                if !refreshed_credentials
1061                    && matches!(
1062                        response.status,
1063                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1064                    )
1065                {
1066                    configuration.qcs_config.refresh().await?;
1067                    refreshed_credentials = true;
1068                    continue;
1069                } else if let Some(duration) = response.retry_delay {
1070                    tokio::time::sleep(duration).await;
1071                    continue;
1072                }
1073
1074                return Err(Error::ResponseError(response));
1075            }
1076            Err(Error::Reqwest(error)) => {
1077                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1078                    tokio::time::sleep(duration).await;
1079                    continue;
1080                }
1081
1082                return Err(Error::Reqwest(error));
1083            }
1084            Err(Error::Io(error)) => {
1085                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1086                    tokio::time::sleep(duration).await;
1087                    continue;
1088                }
1089
1090                return Err(Error::Io(error));
1091            }
1092            Err(error) => return Err(error),
1093        }
1094    }
1095}