Skip to main content

az_rs/
client.rs

1mod poller;
2mod response;
3
4use std::sync::Arc;
5
6use azure_core::{
7    credentials::TokenCredential,
8    http::{
9        policies::{BearerTokenCredentialPolicy, Policy},
10        ClientMethodOptions, ClientOptions, Context, Method, Pipeline, Request, Url,
11    },
12    Result,
13};
14use bytes::Bytes;
15
16use crate::client::poller::Poller;
17use crate::client::response::Response;
18
19#[derive(Debug)]
20pub struct Client {
21    endpoint: Url,
22    pipeline: Pipeline,
23}
24
25impl Client {
26    pub fn new(
27        endpoint: &str,
28        auth_scopes: impl IntoIterator<Item = impl Into<String>>,
29        credential: Arc<dyn TokenCredential>,
30        options: Option<ClientOptions>,
31    ) -> Result<Self> {
32        let endpoint = Url::parse(endpoint)?;
33        let options = options.unwrap_or_default();
34        let auth_policy: Arc<dyn Policy> =
35            Arc::new(BearerTokenCredentialPolicy::new(credential, auth_scopes));
36        let pipeline = Pipeline::new(
37            option_env!("CARGO_PKG_NAME"),
38            option_env!("CARGO_PKG_VERSION"),
39            options,
40            vec![auth_policy],
41            vec![],
42        );
43        Ok(Self { endpoint, pipeline })
44    }
45
46    pub async fn run(
47        &self,
48        method: Method,
49        api_path: &str,
50        api_version: &str,
51        body: Option<Bytes>,
52        options: Option<ClientMethodOptions<'_>>,
53    ) -> Result<Response> {
54        let options = options.unwrap_or_default();
55        let mut url = self.endpoint.clone();
56        url = url.join(api_path)?;
57        url.query_pairs_mut()
58            .append_pair("api-version", api_version);
59        let mut request = Request::new(url, method);
60        request.insert_header("accept", "application/json");
61        if let Some(body) = body {
62            request.insert_header("content-type", "application/json");
63            request.set_body(body);
64        }
65
66        let ctx = Context::with_context(&options.context);
67        let raw_resp = self.pipeline.send(&ctx, &mut request).await?;
68        let resp = Response::from_raw_response(raw_resp).await?;
69
70        // For PUT, POST, PATCH, DELETE operations that can be a LRO, try to
71        if [Method::Put, Method::Post, Method::Delete, Method::Patch].contains(&method) {
72            if let Ok(mut poller) = Poller::new(self.pipeline.clone(), &request, &resp, None).await
73            {
74                return poller.poll_until_done(&ctx, None).await;
75            }
76        }
77
78        Ok(resp)
79    }
80}