Skip to main content

azure_storage_blob/generated/clients/
blob_container_client.rs

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License.
3//
4// Code generated by Microsoft (R) Rust Code Generator. DO NOT EDIT.
5
6use crate::generated::models::{
7    BlobContainerClientAcquireLeaseOptions, BlobContainerClientAcquireLeaseResult,
8    BlobContainerClientBreakLeaseOptions, BlobContainerClientBreakLeaseResult,
9    BlobContainerClientChangeLeaseOptions, BlobContainerClientChangeLeaseResult,
10    BlobContainerClientCreateOptions, BlobContainerClientDeleteOptions,
11    BlobContainerClientFindBlobsByTagsOptions, BlobContainerClientGetAccessPolicyOptions,
12    BlobContainerClientGetAccountInfoOptions, BlobContainerClientGetAccountInfoResult,
13    BlobContainerClientGetPropertiesOptions, BlobContainerClientGetPropertiesResult,
14    BlobContainerClientListBlobsOptions, BlobContainerClientReleaseLeaseOptions,
15    BlobContainerClientReleaseLeaseResult, BlobContainerClientRenewLeaseOptions,
16    BlobContainerClientRenewLeaseResult, BlobContainerClientSetAccessPolicyOptions,
17    BlobContainerClientSetMetadataOptions, FilteredBlobResponse, ListBlobsResponse,
18    SignedIdentifiers,
19};
20use azure_core::{
21    error::CheckSuccessOptions,
22    fmt::SafeDebug,
23    http::{
24        pager::{PagerContinuation, PagerResult, PagerState},
25        ClientOptions, Method, NoFormat, Pager, Pipeline, PipelineSendOptions, RawResponse,
26        Request, RequestContent, Response, Url, UrlExt, XmlFormat,
27    },
28    time::to_rfc7231,
29    tracing, xml, Result,
30};
31use std::collections::HashMap;
32
33#[tracing::client]
34pub struct BlobContainerClient {
35    pub(crate) endpoint: Url,
36    pub(crate) pipeline: Pipeline,
37    pub(crate) version: String,
38}
39
40/// Options used when creating a `BlobContainerClient`
41#[derive(Clone, SafeDebug)]
42pub struct BlobContainerClientOptions {
43    /// Allows customization of the client.
44    pub client_options: ClientOptions,
45    /// Specifies the version of the operation to use for this request.
46    pub version: String,
47}
48
49impl BlobContainerClient {
50    /// Requests a new lease on the specified container.
51    ///
52    /// # Arguments
53    ///
54    /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A
55    ///   non-infinite lease can be between 15 and 60 seconds.
56    /// * `options` - Optional parameters for the request.
57    ///
58    /// ## Response Headers
59    ///
60    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientAcquireLeaseResultHeaders`] trait, which provides
61    /// access to response headers. For example:
62    ///
63    /// ```no_run
64    /// use azure_core::{Result, http::{Response, NoFormat}};
65    /// use azure_storage_blob::models::{BlobContainerClientAcquireLeaseResult, BlobContainerClientAcquireLeaseResultHeaders};
66    /// async fn example() -> Result<()> {
67    ///     let response: Response<BlobContainerClientAcquireLeaseResult, NoFormat> = unimplemented!();
68    ///     // Access response headers
69    ///     if let Some(etag) = response.etag()? {
70    ///         println!("etag: {:?}", etag);
71    ///     }
72    ///     if let Some(last_modified) = response.last_modified()? {
73    ///         println!("last-modified: {:?}", last_modified);
74    ///     }
75    ///     if let Some(lease_id) = response.lease_id()? {
76    ///         println!("x-ms-lease-id: {:?}", lease_id);
77    ///     }
78    ///     Ok(())
79    /// }
80    /// ```
81    ///
82    /// ### Available headers
83    /// * [`etag`()](crate::generated::models::BlobContainerClientAcquireLeaseResultHeaders::etag) - etag
84    /// * [`last_modified`()](crate::generated::models::BlobContainerClientAcquireLeaseResultHeaders::last_modified) - last-modified
85    /// * [`lease_id`()](crate::generated::models::BlobContainerClientAcquireLeaseResultHeaders::lease_id) - x-ms-lease-id
86    ///
87    /// [`BlobContainerClientAcquireLeaseResultHeaders`]: crate::generated::models::BlobContainerClientAcquireLeaseResultHeaders
88    #[tracing::function("Storage.Blob.BlobContainerClient.acquireLease")]
89    pub async fn acquire_lease(
90        &self,
91        duration: i32,
92        options: Option<BlobContainerClientAcquireLeaseOptions<'_>>,
93    ) -> Result<Response<BlobContainerClientAcquireLeaseResult, NoFormat>> {
94        let options = options.unwrap_or_default();
95        let ctx = options.method_options.context.to_borrowed();
96        let mut url = self.endpoint.clone();
97        let mut query_builder = url.query_builder();
98        query_builder
99            .append_pair("comp", "lease")
100            .append_pair("restype", "container");
101        if let Some(timeout) = options.timeout {
102            query_builder.set_pair("timeout", timeout.to_string());
103        }
104        query_builder.build();
105        let mut request = Request::new(url, Method::Put);
106        if let Some(if_modified_since) = options.if_modified_since {
107            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
108        }
109        if let Some(if_unmodified_since) = options.if_unmodified_since {
110            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
111        }
112        request.insert_header("x-ms-lease-action", "acquire");
113        request.insert_header("x-ms-lease-duration", duration.to_string());
114        if let Some(proposed_lease_id) = options.proposed_lease_id.as_ref() {
115            request.insert_header("x-ms-proposed-lease-id", proposed_lease_id);
116        }
117        request.insert_header("x-ms-version", &self.version);
118        let rsp = self
119            .pipeline
120            .send(
121                &ctx,
122                &mut request,
123                Some(PipelineSendOptions {
124                    check_success: CheckSuccessOptions {
125                        success_codes: &[201],
126                    },
127                    ..Default::default()
128                }),
129            )
130            .await?;
131        Ok(rsp.into())
132    }
133
134    /// Ends a lease and ensures that another client can't acquire a new lease until the current lease period has expired.
135    ///
136    /// # Arguments
137    ///
138    /// * `options` - Optional parameters for the request.
139    ///
140    /// ## Response Headers
141    ///
142    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientBreakLeaseResultHeaders`] trait, which provides
143    /// access to response headers. For example:
144    ///
145    /// ```no_run
146    /// use azure_core::{Result, http::{Response, NoFormat}};
147    /// use azure_storage_blob::models::{BlobContainerClientBreakLeaseResult, BlobContainerClientBreakLeaseResultHeaders};
148    /// async fn example() -> Result<()> {
149    ///     let response: Response<BlobContainerClientBreakLeaseResult, NoFormat> = unimplemented!();
150    ///     // Access response headers
151    ///     if let Some(etag) = response.etag()? {
152    ///         println!("etag: {:?}", etag);
153    ///     }
154    ///     if let Some(last_modified) = response.last_modified()? {
155    ///         println!("last-modified: {:?}", last_modified);
156    ///     }
157    ///     if let Some(lease_time) = response.lease_time()? {
158    ///         println!("x-ms-lease-time: {:?}", lease_time);
159    ///     }
160    ///     Ok(())
161    /// }
162    /// ```
163    ///
164    /// ### Available headers
165    /// * [`etag`()](crate::generated::models::BlobContainerClientBreakLeaseResultHeaders::etag) - etag
166    /// * [`last_modified`()](crate::generated::models::BlobContainerClientBreakLeaseResultHeaders::last_modified) - last-modified
167    /// * [`lease_time`()](crate::generated::models::BlobContainerClientBreakLeaseResultHeaders::lease_time) - x-ms-lease-time
168    ///
169    /// [`BlobContainerClientBreakLeaseResultHeaders`]: crate::generated::models::BlobContainerClientBreakLeaseResultHeaders
170    #[tracing::function("Storage.Blob.BlobContainerClient.breakLease")]
171    pub async fn break_lease(
172        &self,
173        options: Option<BlobContainerClientBreakLeaseOptions<'_>>,
174    ) -> Result<Response<BlobContainerClientBreakLeaseResult, NoFormat>> {
175        let options = options.unwrap_or_default();
176        let ctx = options.method_options.context.to_borrowed();
177        let mut url = self.endpoint.clone();
178        let mut query_builder = url.query_builder();
179        query_builder
180            .append_pair("comp", "lease")
181            .append_pair("restype", "container");
182        if let Some(timeout) = options.timeout {
183            query_builder.set_pair("timeout", timeout.to_string());
184        }
185        query_builder.build();
186        let mut request = Request::new(url, Method::Put);
187        if let Some(if_modified_since) = options.if_modified_since {
188            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
189        }
190        if let Some(if_unmodified_since) = options.if_unmodified_since {
191            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
192        }
193        request.insert_header("x-ms-lease-action", "break");
194        if let Some(break_period) = options.break_period {
195            request.insert_header("x-ms-lease-break-period", break_period.to_string());
196        }
197        request.insert_header("x-ms-version", &self.version);
198        let rsp = self
199            .pipeline
200            .send(
201                &ctx,
202                &mut request,
203                Some(PipelineSendOptions {
204                    check_success: CheckSuccessOptions {
205                        success_codes: &[202],
206                    },
207                    ..Default::default()
208                }),
209            )
210            .await?;
211        Ok(rsp.into())
212    }
213
214    /// Change the ID of an existing lease.
215    ///
216    /// # Arguments
217    ///
218    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
219    /// * `proposed_lease_id` - The proposed lease ID for the lease.
220    /// * `options` - Optional parameters for the request.
221    ///
222    /// ## Response Headers
223    ///
224    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientChangeLeaseResultHeaders`] trait, which provides
225    /// access to response headers. For example:
226    ///
227    /// ```no_run
228    /// use azure_core::{Result, http::{Response, NoFormat}};
229    /// use azure_storage_blob::models::{BlobContainerClientChangeLeaseResult, BlobContainerClientChangeLeaseResultHeaders};
230    /// async fn example() -> Result<()> {
231    ///     let response: Response<BlobContainerClientChangeLeaseResult, NoFormat> = unimplemented!();
232    ///     // Access response headers
233    ///     if let Some(etag) = response.etag()? {
234    ///         println!("etag: {:?}", etag);
235    ///     }
236    ///     if let Some(last_modified) = response.last_modified()? {
237    ///         println!("last-modified: {:?}", last_modified);
238    ///     }
239    ///     if let Some(lease_id) = response.lease_id()? {
240    ///         println!("x-ms-lease-id: {:?}", lease_id);
241    ///     }
242    ///     Ok(())
243    /// }
244    /// ```
245    ///
246    /// ### Available headers
247    /// * [`etag`()](crate::generated::models::BlobContainerClientChangeLeaseResultHeaders::etag) - etag
248    /// * [`last_modified`()](crate::generated::models::BlobContainerClientChangeLeaseResultHeaders::last_modified) - last-modified
249    /// * [`lease_id`()](crate::generated::models::BlobContainerClientChangeLeaseResultHeaders::lease_id) - x-ms-lease-id
250    ///
251    /// [`BlobContainerClientChangeLeaseResultHeaders`]: crate::generated::models::BlobContainerClientChangeLeaseResultHeaders
252    #[tracing::function("Storage.Blob.BlobContainerClient.changeLease")]
253    pub async fn change_lease(
254        &self,
255        lease_id: String,
256        proposed_lease_id: String,
257        options: Option<BlobContainerClientChangeLeaseOptions<'_>>,
258    ) -> Result<Response<BlobContainerClientChangeLeaseResult, NoFormat>> {
259        let options = options.unwrap_or_default();
260        let ctx = options.method_options.context.to_borrowed();
261        let mut url = self.endpoint.clone();
262        let mut query_builder = url.query_builder();
263        query_builder
264            .append_pair("comp", "lease")
265            .append_pair("restype", "container");
266        if let Some(timeout) = options.timeout {
267            query_builder.set_pair("timeout", timeout.to_string());
268        }
269        query_builder.build();
270        let mut request = Request::new(url, Method::Put);
271        if let Some(if_modified_since) = options.if_modified_since {
272            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
273        }
274        if let Some(if_unmodified_since) = options.if_unmodified_since {
275            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
276        }
277        request.insert_header("x-ms-lease-action", "change");
278        request.insert_header("x-ms-lease-id", lease_id);
279        request.insert_header("x-ms-proposed-lease-id", proposed_lease_id);
280        request.insert_header("x-ms-version", &self.version);
281        let rsp = self
282            .pipeline
283            .send(
284                &ctx,
285                &mut request,
286                Some(PipelineSendOptions {
287                    check_success: CheckSuccessOptions {
288                        success_codes: &[200],
289                    },
290                    ..Default::default()
291                }),
292            )
293            .await?;
294        Ok(rsp.into())
295    }
296
297    /// Creates a new container in the specified account. If the container with the same name already exists, the operation fails.
298    ///
299    /// # Arguments
300    ///
301    /// * `options` - Optional parameters for the request.
302    #[tracing::function("Storage.Blob.BlobContainerClient.create")]
303    pub async fn create(
304        &self,
305        options: Option<BlobContainerClientCreateOptions<'_>>,
306    ) -> Result<Response<(), NoFormat>> {
307        let options = options.unwrap_or_default();
308        let ctx = options.method_options.context.to_borrowed();
309        let mut url = self.endpoint.clone();
310        let mut query_builder = url.query_builder();
311        query_builder.append_pair("restype", "container");
312        if let Some(timeout) = options.timeout {
313            query_builder.set_pair("timeout", timeout.to_string());
314        }
315        query_builder.build();
316        let mut request = Request::new(url, Method::Put);
317        if let Some(access) = options.access.as_ref() {
318            request.insert_header("x-ms-blob-public-access", access.to_string());
319        }
320        if let Some(default_encryption_scope) = options.default_encryption_scope.as_ref() {
321            request.insert_header("x-ms-default-encryption-scope", default_encryption_scope);
322        }
323        if let Some(prevent_encryption_scope_override) = options.prevent_encryption_scope_override {
324            request.insert_header(
325                "x-ms-deny-encryption-scope-override",
326                prevent_encryption_scope_override.to_string(),
327            );
328        }
329        if let Some(metadata) = options.metadata.as_ref() {
330            for (k, v) in metadata {
331                request.insert_header(format!("x-ms-meta-{k}"), v);
332            }
333        }
334        request.insert_header("x-ms-version", &self.version);
335        let rsp = self
336            .pipeline
337            .send(
338                &ctx,
339                &mut request,
340                Some(PipelineSendOptions {
341                    check_success: CheckSuccessOptions {
342                        success_codes: &[201],
343                    },
344                    ..Default::default()
345                }),
346            )
347            .await?;
348        Ok(rsp.into())
349    }
350
351    /// Deletes the specified container.
352    ///
353    /// # Arguments
354    ///
355    /// * `options` - Optional parameters for the request.
356    #[tracing::function("Storage.Blob.BlobContainerClient.delete")]
357    pub async fn delete(
358        &self,
359        options: Option<BlobContainerClientDeleteOptions<'_>>,
360    ) -> Result<Response<(), NoFormat>> {
361        let options = options.unwrap_or_default();
362        let ctx = options.method_options.context.to_borrowed();
363        let mut url = self.endpoint.clone();
364        let mut query_builder = url.query_builder();
365        query_builder.append_pair("restype", "container");
366        if let Some(timeout) = options.timeout {
367            query_builder.set_pair("timeout", timeout.to_string());
368        }
369        query_builder.build();
370        let mut request = Request::new(url, Method::Delete);
371        if let Some(if_modified_since) = options.if_modified_since {
372            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
373        }
374        if let Some(if_unmodified_since) = options.if_unmodified_since {
375            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
376        }
377        if let Some(lease_id) = options.lease_id.as_ref() {
378            request.insert_header("x-ms-lease-id", lease_id);
379        }
380        request.insert_header("x-ms-version", &self.version);
381        let rsp = self
382            .pipeline
383            .send(
384                &ctx,
385                &mut request,
386                Some(PipelineSendOptions {
387                    check_success: CheckSuccessOptions {
388                        success_codes: &[202],
389                    },
390                    ..Default::default()
391                }),
392            )
393            .await?;
394        Ok(rsp.into())
395    }
396
397    /// Lists blobs in the specified container whose tags match a given search expression.
398    ///
399    /// # Arguments
400    ///
401    /// * `filter_expression` - Filters the results to return only blobs whose tags match the specified expression.
402    /// * `options` - Optional parameters for the request.
403    #[tracing::function("Storage.Blob.BlobContainerClient.findBlobsByTags")]
404    pub fn find_blobs_by_tags(
405        &self,
406        filter_expression: &str,
407        options: Option<BlobContainerClientFindBlobsByTagsOptions<'_>>,
408    ) -> Result<Pager<FilteredBlobResponse, XmlFormat>> {
409        let options = options.unwrap_or_default().into_owned();
410        let pipeline = self.pipeline.clone();
411        let mut first_url = self.endpoint.clone();
412        let mut query_builder = first_url.query_builder();
413        query_builder
414            .append_pair("comp", "blobs")
415            .append_pair("restype", "container");
416        if let Some(include) = options.include.as_ref() {
417            query_builder.set_pair(
418                "include",
419                include
420                    .iter()
421                    .map(|i| i.to_string())
422                    .collect::<Vec<String>>()
423                    .join(","),
424            );
425        }
426        if let Some(marker) = options.marker.as_ref() {
427            query_builder.set_pair("marker", marker);
428        }
429        if let Some(maxresults) = options.maxresults {
430            query_builder.set_pair("maxresults", maxresults.to_string());
431        }
432        if let Some(timeout) = options.timeout {
433            query_builder.set_pair("timeout", timeout.to_string());
434        }
435        query_builder.set_pair("where", filter_expression);
436        query_builder.build();
437        #[derive(serde::Deserialize)]
438        struct BlobContainerClientFindBlobsByTagsPage {
439            #[serde(rename = "NextMarker")]
440            next_marker: Option<String>,
441        }
442
443        let version = self.version.clone();
444        Ok(Pager::new(
445            move |marker: PagerState, pager_options| {
446                let mut url = first_url.clone();
447                if let PagerState::More(marker) = marker {
448                    let mut query_builder = url.query_builder();
449                    query_builder.set_pair("marker", marker.as_ref());
450                    query_builder.build();
451                }
452                let mut request = Request::new(url, Method::Get);
453                request.insert_header("accept", "application/xml");
454                request.insert_header("x-ms-version", &version);
455                let pipeline = pipeline.clone();
456                Box::pin(async move {
457                    let rsp = pipeline
458                        .send(
459                            &pager_options.context,
460                            &mut request,
461                            Some(PipelineSendOptions {
462                                check_success: CheckSuccessOptions {
463                                    success_codes: &[200],
464                                },
465                                ..Default::default()
466                            }),
467                        )
468                        .await?;
469                    let (status, headers, body) = rsp.deconstruct();
470                    let res: BlobContainerClientFindBlobsByTagsPage = xml::from_xml(&body)?;
471                    let rsp = RawResponse::from_bytes(status, headers, body).into();
472                    Ok(match res.next_marker {
473                        Some(next_marker) if !next_marker.is_empty() => PagerResult::More {
474                            response: rsp,
475                            continuation: PagerContinuation::Token(next_marker),
476                        },
477                        _ => PagerResult::Done { response: rsp },
478                    })
479                })
480            },
481            Some(options.method_options),
482        ))
483    }
484
485    /// Gets the permissions for the specified container.
486    ///
487    /// # Arguments
488    ///
489    /// * `options` - Optional parameters for the request.
490    ///
491    /// ## Response Headers
492    ///
493    /// The returned [`Response`](azure_core::http::Response) implements the [`SignedIdentifiersHeaders`] trait, which provides
494    /// access to response headers. For example:
495    ///
496    /// ```no_run
497    /// use azure_core::{Result, http::{Response, XmlFormat}};
498    /// use azure_storage_blob::models::{SignedIdentifiers, SignedIdentifiersHeaders};
499    /// async fn example() -> Result<()> {
500    ///     let response: Response<SignedIdentifiers, XmlFormat> = unimplemented!();
501    ///     // Access response headers
502    ///     if let Some(etag) = response.etag()? {
503    ///         println!("etag: {:?}", etag);
504    ///     }
505    ///     if let Some(last_modified) = response.last_modified()? {
506    ///         println!("last-modified: {:?}", last_modified);
507    ///     }
508    ///     if let Some(access) = response.access()? {
509    ///         println!("x-ms-blob-public-access: {:?}", access);
510    ///     }
511    ///     Ok(())
512    /// }
513    /// ```
514    ///
515    /// ### Available headers
516    /// * [`etag`()](crate::generated::models::SignedIdentifiersHeaders::etag) - etag
517    /// * [`last_modified`()](crate::generated::models::SignedIdentifiersHeaders::last_modified) - last-modified
518    /// * [`access`()](crate::generated::models::SignedIdentifiersHeaders::access) - x-ms-blob-public-access
519    ///
520    /// [`SignedIdentifiersHeaders`]: crate::generated::models::SignedIdentifiersHeaders
521    #[tracing::function("Storage.Blob.BlobContainerClient.getAccessPolicy")]
522    pub async fn get_access_policy(
523        &self,
524        options: Option<BlobContainerClientGetAccessPolicyOptions<'_>>,
525    ) -> Result<Response<SignedIdentifiers, XmlFormat>> {
526        let options = options.unwrap_or_default();
527        let ctx = options.method_options.context.to_borrowed();
528        let mut url = self.endpoint.clone();
529        let mut query_builder = url.query_builder();
530        query_builder
531            .append_pair("comp", "acl")
532            .append_pair("restype", "container");
533        if let Some(timeout) = options.timeout {
534            query_builder.set_pair("timeout", timeout.to_string());
535        }
536        query_builder.build();
537        let mut request = Request::new(url, Method::Get);
538        request.insert_header("accept", "application/xml");
539        if let Some(lease_id) = options.lease_id.as_ref() {
540            request.insert_header("x-ms-lease-id", lease_id);
541        }
542        request.insert_header("x-ms-version", &self.version);
543        let rsp = self
544            .pipeline
545            .send(
546                &ctx,
547                &mut request,
548                Some(PipelineSendOptions {
549                    check_success: CheckSuccessOptions {
550                        success_codes: &[200],
551                    },
552                    ..Default::default()
553                }),
554            )
555            .await?;
556        Ok(rsp.into())
557    }
558
559    /// Returns information about the storage account.
560    ///
561    /// # Arguments
562    ///
563    /// * `options` - Optional parameters for the request.
564    ///
565    /// ## Response Headers
566    ///
567    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientGetAccountInfoResultHeaders`] trait, which provides
568    /// access to response headers. For example:
569    ///
570    /// ```no_run
571    /// use azure_core::{Result, http::{Response, NoFormat}};
572    /// use azure_storage_blob::models::{BlobContainerClientGetAccountInfoResult, BlobContainerClientGetAccountInfoResultHeaders};
573    /// async fn example() -> Result<()> {
574    ///     let response: Response<BlobContainerClientGetAccountInfoResult, NoFormat> = unimplemented!();
575    ///     // Access response headers
576    ///     if let Some(account_kind) = response.account_kind()? {
577    ///         println!("x-ms-account-kind: {:?}", account_kind);
578    ///     }
579    ///     if let Some(is_hierarchical_namespace_enabled) = response.is_hierarchical_namespace_enabled()? {
580    ///         println!("x-ms-is-hns-enabled: {:?}", is_hierarchical_namespace_enabled);
581    ///     }
582    ///     if let Some(sku_name) = response.sku_name()? {
583    ///         println!("x-ms-sku-name: {:?}", sku_name);
584    ///     }
585    ///     Ok(())
586    /// }
587    /// ```
588    ///
589    /// ### Available headers
590    /// * [`account_kind`()](crate::generated::models::BlobContainerClientGetAccountInfoResultHeaders::account_kind) - x-ms-account-kind
591    /// * [`is_hierarchical_namespace_enabled`()](crate::generated::models::BlobContainerClientGetAccountInfoResultHeaders::is_hierarchical_namespace_enabled) - x-ms-is-hns-enabled
592    /// * [`sku_name`()](crate::generated::models::BlobContainerClientGetAccountInfoResultHeaders::sku_name) - x-ms-sku-name
593    ///
594    /// [`BlobContainerClientGetAccountInfoResultHeaders`]: crate::generated::models::BlobContainerClientGetAccountInfoResultHeaders
595    #[tracing::function("Storage.Blob.BlobContainerClient.getAccountInfo")]
596    pub async fn get_account_info(
597        &self,
598        options: Option<BlobContainerClientGetAccountInfoOptions<'_>>,
599    ) -> Result<Response<BlobContainerClientGetAccountInfoResult, NoFormat>> {
600        let options = options.unwrap_or_default();
601        let ctx = options.method_options.context.to_borrowed();
602        let mut url = self.endpoint.clone();
603        let mut query_builder = url.query_builder();
604        query_builder
605            .append_pair("comp", "properties")
606            .append_pair("restype", "account");
607        if let Some(timeout) = options.timeout {
608            query_builder.set_pair("timeout", timeout.to_string());
609        }
610        query_builder.build();
611        let mut request = Request::new(url, Method::Get);
612        request.insert_header("x-ms-version", &self.version);
613        let rsp = self
614            .pipeline
615            .send(
616                &ctx,
617                &mut request,
618                Some(PipelineSendOptions {
619                    check_success: CheckSuccessOptions {
620                        success_codes: &[200],
621                    },
622                    ..Default::default()
623                }),
624            )
625            .await?;
626        Ok(rsp.into())
627    }
628
629    /// Returns all user-defined metadata and system properties for the specified container. The data returned does not include
630    /// the container's list of blobs.
631    ///
632    /// # Arguments
633    ///
634    /// * `options` - Optional parameters for the request.
635    ///
636    /// ## Response Headers
637    ///
638    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientGetPropertiesResultHeaders`] trait, which provides
639    /// access to response headers. For example:
640    ///
641    /// ```no_run
642    /// use azure_core::{Result, http::{Response, NoFormat}};
643    /// use azure_storage_blob::models::{BlobContainerClientGetPropertiesResult, BlobContainerClientGetPropertiesResultHeaders};
644    /// async fn example() -> Result<()> {
645    ///     let response: Response<BlobContainerClientGetPropertiesResult, NoFormat> = unimplemented!();
646    ///     // Access response headers
647    ///     if let Some(etag) = response.etag()? {
648    ///         println!("etag: {:?}", etag);
649    ///     }
650    ///     if let Some(last_modified) = response.last_modified()? {
651    ///         println!("last-modified: {:?}", last_modified);
652    ///     }
653    ///     if let Some(access) = response.access()? {
654    ///         println!("x-ms-blob-public-access: {:?}", access);
655    ///     }
656    ///     Ok(())
657    /// }
658    /// ```
659    ///
660    /// ### Available headers
661    /// * [`etag`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::etag) - etag
662    /// * [`last_modified`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::last_modified) - last-modified
663    /// * [`access`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::access) - x-ms-blob-public-access
664    /// * [`default_encryption_scope`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::default_encryption_scope) - x-ms-default-encryption-scope
665    /// * [`prevent_encryption_scope_override`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::prevent_encryption_scope_override) - x-ms-deny-encryption-scope-override
666    /// * [`has_immutability_policy`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::has_immutability_policy) - x-ms-has-immutability-policy
667    /// * [`has_legal_hold`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::has_legal_hold) - x-ms-has-legal-hold
668    /// * [`is_immutable_storage_with_versioning_enabled`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::is_immutable_storage_with_versioning_enabled) - x-ms-immutable-storage-with-versioning-enabled
669    /// * [`duration`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::duration) - x-ms-lease-duration
670    /// * [`lease_state`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::lease_state) - x-ms-lease-state
671    /// * [`lease_status`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::lease_status) - x-ms-lease-status
672    /// * [`metadata`()](crate::generated::models::BlobContainerClientGetPropertiesResultHeaders::metadata) - x-ms-meta
673    ///
674    /// [`BlobContainerClientGetPropertiesResultHeaders`]: crate::generated::models::BlobContainerClientGetPropertiesResultHeaders
675    #[tracing::function("Storage.Blob.BlobContainerClient.getProperties")]
676    pub async fn get_properties(
677        &self,
678        options: Option<BlobContainerClientGetPropertiesOptions<'_>>,
679    ) -> Result<Response<BlobContainerClientGetPropertiesResult, NoFormat>> {
680        let options = options.unwrap_or_default();
681        let ctx = options.method_options.context.to_borrowed();
682        let mut url = self.endpoint.clone();
683        let mut query_builder = url.query_builder();
684        query_builder.append_pair("restype", "container");
685        if let Some(timeout) = options.timeout {
686            query_builder.set_pair("timeout", timeout.to_string());
687        }
688        query_builder.build();
689        let mut request = Request::new(url, Method::Get);
690        if let Some(lease_id) = options.lease_id.as_ref() {
691            request.insert_header("x-ms-lease-id", lease_id);
692        }
693        request.insert_header("x-ms-version", &self.version);
694        let rsp = self
695            .pipeline
696            .send(
697                &ctx,
698                &mut request,
699                Some(PipelineSendOptions {
700                    check_success: CheckSuccessOptions {
701                        success_codes: &[200],
702                    },
703                    ..Default::default()
704                }),
705            )
706            .await?;
707        Ok(rsp.into())
708    }
709
710    /// Returns a list of the blobs in the specified container.
711    ///
712    /// # Arguments
713    ///
714    /// * `options` - Optional parameters for the request.
715    #[tracing::function("Storage.Blob.BlobContainerClient.listBlobs")]
716    pub fn list_blobs(
717        &self,
718        options: Option<BlobContainerClientListBlobsOptions<'_>>,
719    ) -> Result<Pager<ListBlobsResponse, XmlFormat>> {
720        let options = options.unwrap_or_default().into_owned();
721        let pipeline = self.pipeline.clone();
722        let mut first_url = self.endpoint.clone();
723        let mut query_builder = first_url.query_builder();
724        query_builder
725            .append_pair("comp", "list")
726            .append_pair("restype", "container");
727        if let Some(include) = options.include.as_ref() {
728            query_builder.set_pair(
729                "include",
730                include
731                    .iter()
732                    .map(|i| i.to_string())
733                    .collect::<Vec<String>>()
734                    .join(","),
735            );
736        }
737        if let Some(marker) = options.marker.as_ref() {
738            query_builder.set_pair("marker", marker);
739        }
740        if let Some(maxresults) = options.maxresults {
741            query_builder.set_pair("maxresults", maxresults.to_string());
742        }
743        if let Some(prefix) = options.prefix.as_ref() {
744            query_builder.set_pair("prefix", prefix);
745        }
746        if let Some(start_from) = options.start_from.as_ref() {
747            query_builder.set_pair("startFrom", start_from);
748        }
749        if let Some(timeout) = options.timeout {
750            query_builder.set_pair("timeout", timeout.to_string());
751        }
752        query_builder.build();
753        #[derive(serde::Deserialize)]
754        struct BlobContainerClientListBlobsPage {
755            #[serde(rename = "NextMarker")]
756            next_marker: Option<String>,
757        }
758
759        let version = self.version.clone();
760        Ok(Pager::new(
761            move |marker: PagerState, pager_options| {
762                let mut url = first_url.clone();
763                if let PagerState::More(marker) = marker {
764                    let mut query_builder = url.query_builder();
765                    query_builder.set_pair("marker", marker.as_ref());
766                    query_builder.build();
767                }
768                let mut request = Request::new(url, Method::Get);
769                request.insert_header("accept", "application/xml");
770                request.insert_header("x-ms-version", &version);
771                let pipeline = pipeline.clone();
772                Box::pin(async move {
773                    let rsp = pipeline
774                        .send(
775                            &pager_options.context,
776                            &mut request,
777                            Some(PipelineSendOptions {
778                                check_success: CheckSuccessOptions {
779                                    success_codes: &[200],
780                                },
781                                ..Default::default()
782                            }),
783                        )
784                        .await?;
785                    let (status, headers, body) = rsp.deconstruct();
786                    let res: BlobContainerClientListBlobsPage = xml::from_xml(&body)?;
787                    let rsp = RawResponse::from_bytes(status, headers, body).into();
788                    Ok(match res.next_marker {
789                        Some(next_marker) if !next_marker.is_empty() => PagerResult::More {
790                            response: rsp,
791                            continuation: PagerContinuation::Token(next_marker),
792                        },
793                        _ => PagerResult::Done { response: rsp },
794                    })
795                })
796            },
797            Some(options.method_options),
798        ))
799    }
800
801    /// Frees the lease if it's no longer needed, so that another client can immediately acquire a lease against the container.
802    ///
803    /// # Arguments
804    ///
805    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
806    /// * `options` - Optional parameters for the request.
807    ///
808    /// ## Response Headers
809    ///
810    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientReleaseLeaseResultHeaders`] trait, which provides
811    /// access to response headers. For example:
812    ///
813    /// ```no_run
814    /// use azure_core::{Result, http::{Response, NoFormat}};
815    /// use azure_storage_blob::models::{BlobContainerClientReleaseLeaseResult, BlobContainerClientReleaseLeaseResultHeaders};
816    /// async fn example() -> Result<()> {
817    ///     let response: Response<BlobContainerClientReleaseLeaseResult, NoFormat> = unimplemented!();
818    ///     // Access response headers
819    ///     if let Some(etag) = response.etag()? {
820    ///         println!("etag: {:?}", etag);
821    ///     }
822    ///     if let Some(last_modified) = response.last_modified()? {
823    ///         println!("last-modified: {:?}", last_modified);
824    ///     }
825    ///     Ok(())
826    /// }
827    /// ```
828    ///
829    /// ### Available headers
830    /// * [`etag`()](crate::generated::models::BlobContainerClientReleaseLeaseResultHeaders::etag) - etag
831    /// * [`last_modified`()](crate::generated::models::BlobContainerClientReleaseLeaseResultHeaders::last_modified) - last-modified
832    ///
833    /// [`BlobContainerClientReleaseLeaseResultHeaders`]: crate::generated::models::BlobContainerClientReleaseLeaseResultHeaders
834    #[tracing::function("Storage.Blob.BlobContainerClient.releaseLease")]
835    pub async fn release_lease(
836        &self,
837        lease_id: String,
838        options: Option<BlobContainerClientReleaseLeaseOptions<'_>>,
839    ) -> Result<Response<BlobContainerClientReleaseLeaseResult, NoFormat>> {
840        let options = options.unwrap_or_default();
841        let ctx = options.method_options.context.to_borrowed();
842        let mut url = self.endpoint.clone();
843        let mut query_builder = url.query_builder();
844        query_builder
845            .append_pair("comp", "lease")
846            .append_pair("restype", "container");
847        if let Some(timeout) = options.timeout {
848            query_builder.set_pair("timeout", timeout.to_string());
849        }
850        query_builder.build();
851        let mut request = Request::new(url, Method::Put);
852        if let Some(if_modified_since) = options.if_modified_since {
853            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
854        }
855        if let Some(if_unmodified_since) = options.if_unmodified_since {
856            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
857        }
858        request.insert_header("x-ms-lease-action", "release");
859        request.insert_header("x-ms-lease-id", lease_id);
860        request.insert_header("x-ms-version", &self.version);
861        let rsp = self
862            .pipeline
863            .send(
864                &ctx,
865                &mut request,
866                Some(PipelineSendOptions {
867                    check_success: CheckSuccessOptions {
868                        success_codes: &[200],
869                    },
870                    ..Default::default()
871                }),
872            )
873            .await?;
874        Ok(rsp.into())
875    }
876
877    /// Renews an existing lease.
878    ///
879    /// # Arguments
880    ///
881    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
882    /// * `options` - Optional parameters for the request.
883    ///
884    /// ## Response Headers
885    ///
886    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobContainerClientRenewLeaseResultHeaders`] trait, which provides
887    /// access to response headers. For example:
888    ///
889    /// ```no_run
890    /// use azure_core::{Result, http::{Response, NoFormat}};
891    /// use azure_storage_blob::models::{BlobContainerClientRenewLeaseResult, BlobContainerClientRenewLeaseResultHeaders};
892    /// async fn example() -> Result<()> {
893    ///     let response: Response<BlobContainerClientRenewLeaseResult, NoFormat> = unimplemented!();
894    ///     // Access response headers
895    ///     if let Some(etag) = response.etag()? {
896    ///         println!("etag: {:?}", etag);
897    ///     }
898    ///     if let Some(last_modified) = response.last_modified()? {
899    ///         println!("last-modified: {:?}", last_modified);
900    ///     }
901    ///     if let Some(lease_id) = response.lease_id()? {
902    ///         println!("x-ms-lease-id: {:?}", lease_id);
903    ///     }
904    ///     Ok(())
905    /// }
906    /// ```
907    ///
908    /// ### Available headers
909    /// * [`etag`()](crate::generated::models::BlobContainerClientRenewLeaseResultHeaders::etag) - etag
910    /// * [`last_modified`()](crate::generated::models::BlobContainerClientRenewLeaseResultHeaders::last_modified) - last-modified
911    /// * [`lease_id`()](crate::generated::models::BlobContainerClientRenewLeaseResultHeaders::lease_id) - x-ms-lease-id
912    ///
913    /// [`BlobContainerClientRenewLeaseResultHeaders`]: crate::generated::models::BlobContainerClientRenewLeaseResultHeaders
914    #[tracing::function("Storage.Blob.BlobContainerClient.renewLease")]
915    pub async fn renew_lease(
916        &self,
917        lease_id: String,
918        options: Option<BlobContainerClientRenewLeaseOptions<'_>>,
919    ) -> Result<Response<BlobContainerClientRenewLeaseResult, NoFormat>> {
920        let options = options.unwrap_or_default();
921        let ctx = options.method_options.context.to_borrowed();
922        let mut url = self.endpoint.clone();
923        let mut query_builder = url.query_builder();
924        query_builder
925            .append_pair("comp", "lease")
926            .append_pair("restype", "container");
927        if let Some(timeout) = options.timeout {
928            query_builder.set_pair("timeout", timeout.to_string());
929        }
930        query_builder.build();
931        let mut request = Request::new(url, Method::Put);
932        if let Some(if_modified_since) = options.if_modified_since {
933            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
934        }
935        if let Some(if_unmodified_since) = options.if_unmodified_since {
936            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
937        }
938        request.insert_header("x-ms-lease-action", "renew");
939        request.insert_header("x-ms-lease-id", lease_id);
940        request.insert_header("x-ms-version", &self.version);
941        let rsp = self
942            .pipeline
943            .send(
944                &ctx,
945                &mut request,
946                Some(PipelineSendOptions {
947                    check_success: CheckSuccessOptions {
948                        success_codes: &[200],
949                    },
950                    ..Default::default()
951                }),
952            )
953            .await?;
954        Ok(rsp.into())
955    }
956
957    /// Sets the permissions for the specified container.
958    ///
959    /// # Arguments
960    ///
961    /// * `container_acl` - The access control list for the container.
962    /// * `options` - Optional parameters for the request.
963    #[tracing::function("Storage.Blob.BlobContainerClient.setAccessPolicy")]
964    pub async fn set_access_policy(
965        &self,
966        container_acl: RequestContent<SignedIdentifiers, XmlFormat>,
967        options: Option<BlobContainerClientSetAccessPolicyOptions<'_>>,
968    ) -> Result<Response<(), NoFormat>> {
969        let options = options.unwrap_or_default();
970        let ctx = options.method_options.context.to_borrowed();
971        let mut url = self.endpoint.clone();
972        let mut query_builder = url.query_builder();
973        query_builder
974            .append_pair("comp", "acl")
975            .append_pair("restype", "container");
976        if let Some(timeout) = options.timeout {
977            query_builder.set_pair("timeout", timeout.to_string());
978        }
979        query_builder.build();
980        let mut request = Request::new(url, Method::Put);
981        if let Some(if_modified_since) = options.if_modified_since {
982            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
983        }
984        if let Some(if_unmodified_since) = options.if_unmodified_since {
985            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
986        }
987        if let Some(access) = options.access.as_ref() {
988            request.insert_header("x-ms-blob-public-access", access.to_string());
989        }
990        if let Some(lease_id) = options.lease_id.as_ref() {
991            request.insert_header("x-ms-lease-id", lease_id);
992        }
993        request.insert_header("x-ms-version", &self.version);
994        request.insert_header("content-type", "application/xml");
995        request.set_body(container_acl);
996        let rsp = self
997            .pipeline
998            .send(
999                &ctx,
1000                &mut request,
1001                Some(PipelineSendOptions {
1002                    check_success: CheckSuccessOptions {
1003                        success_codes: &[200],
1004                    },
1005                    ..Default::default()
1006                }),
1007            )
1008            .await?;
1009        Ok(rsp.into())
1010    }
1011
1012    /// Sets user-defined metadata for the specified container.
1013    ///
1014    /// # Arguments
1015    ///
1016    /// * `metadata` - The metadata headers.
1017    /// * `options` - Optional parameters for the request.
1018    #[tracing::function("Storage.Blob.BlobContainerClient.setMetadata")]
1019    pub async fn set_metadata(
1020        &self,
1021        metadata: &HashMap<String, String>,
1022        options: Option<BlobContainerClientSetMetadataOptions<'_>>,
1023    ) -> Result<Response<(), NoFormat>> {
1024        let options = options.unwrap_or_default();
1025        let ctx = options.method_options.context.to_borrowed();
1026        let mut url = self.endpoint.clone();
1027        let mut query_builder = url.query_builder();
1028        query_builder
1029            .append_pair("comp", "metadata")
1030            .append_pair("restype", "container");
1031        if let Some(timeout) = options.timeout {
1032            query_builder.set_pair("timeout", timeout.to_string());
1033        }
1034        query_builder.build();
1035        let mut request = Request::new(url, Method::Put);
1036        if let Some(if_modified_since) = options.if_modified_since {
1037            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1038        }
1039        if let Some(lease_id) = options.lease_id.as_ref() {
1040            request.insert_header("x-ms-lease-id", lease_id);
1041        }
1042        for (k, v) in metadata {
1043            request.insert_header(format!("x-ms-meta-{k}"), v);
1044        }
1045        request.insert_header("x-ms-version", &self.version);
1046        let rsp = self
1047            .pipeline
1048            .send(
1049                &ctx,
1050                &mut request,
1051                Some(PipelineSendOptions {
1052                    check_success: CheckSuccessOptions {
1053                        success_codes: &[200],
1054                    },
1055                    ..Default::default()
1056                }),
1057            )
1058            .await?;
1059        Ok(rsp.into())
1060    }
1061}
1062
1063/// Default value for [`BlobContainerClientOptions::version`].
1064pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
1065
1066impl Default for BlobContainerClientOptions {
1067    fn default() -> Self {
1068        Self {
1069            client_options: ClientOptions::default(),
1070            version: String::from(DEFAULT_VERSION),
1071        }
1072    }
1073}