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}