Skip to main content

azure_storage_blob/generated/clients/
blob_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    AccessTier, BlobClientAbortCopyOptions, BlobClientAcquireLeaseOptions,
8    BlobClientAcquireLeaseResult, BlobClientBreakLeaseOptions, BlobClientBreakLeaseResult,
9    BlobClientChangeLeaseOptions, BlobClientChangeLeaseResult, BlobClientCreateSnapshotOptions,
10    BlobClientCreateSnapshotResult, BlobClientDeleteImmutabilityPolicyOptions,
11    BlobClientDeleteOptions, BlobClientDownloadInternalOptions, BlobClientDownloadInternalResult,
12    BlobClientGetAccountInfoOptions, BlobClientGetAccountInfoResult,
13    BlobClientGetPropertiesOptions, BlobClientGetPropertiesResult, BlobClientGetTagsOptions,
14    BlobClientReleaseLeaseOptions, BlobClientReleaseLeaseResult, BlobClientRenewLeaseOptions,
15    BlobClientRenewLeaseResult, BlobClientSetImmutabilityPolicyOptions,
16    BlobClientSetLegalHoldOptions, BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions,
17    BlobClientSetTagsOptions, BlobClientSetTierOptions, BlobClientStartCopyFromUrlOptions,
18    BlobClientStartCopyFromUrlResult, BlobClientUndeleteOptions, BlobTags,
19};
20use azure_core::{
21    base64,
22    error::CheckSuccessOptions,
23    fmt::SafeDebug,
24    http::{
25        AsyncResponse, ClientOptions, Method, NoFormat, Pipeline, PipelineSendOptions,
26        PipelineStreamOptions, Request, RequestContent, Response, Url, UrlExt, XmlFormat,
27    },
28    time::{to_rfc7231, OffsetDateTime},
29    tracing, Result,
30};
31use std::collections::HashMap;
32
33#[tracing::client]
34pub struct BlobClient {
35    pub(crate) endpoint: Url,
36    pub(crate) pipeline: Pipeline,
37    pub(crate) version: String,
38}
39
40/// Options used when creating a `BlobClient`
41#[derive(Clone, SafeDebug)]
42pub struct BlobClientOptions {
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 BlobClient {
50    /// Aborts a pending asynchronous copy operation and leaves a destination blob with zero length and full metadata.
51    ///
52    /// # Arguments
53    ///
54    /// * `copy_id` - The ID of the copy to be aborted.
55    /// * `options` - Optional parameters for the request.
56    #[tracing::function("Storage.Blob.BlobClient.abortCopyFromUrl")]
57    pub async fn abort_copy(
58        &self,
59        copy_id: &str,
60        options: Option<BlobClientAbortCopyOptions<'_>>,
61    ) -> Result<Response<(), NoFormat>> {
62        let options = options.unwrap_or_default();
63        let ctx = options.method_options.context.to_borrowed();
64        let mut url = self.endpoint.clone();
65        let mut query_builder = url.query_builder();
66        query_builder.append_pair("comp", "copy");
67        query_builder.set_pair("copyid", copy_id);
68        if let Some(timeout) = options.timeout {
69            query_builder.set_pair("timeout", timeout.to_string());
70        }
71        query_builder.build();
72        let mut request = Request::new(url, Method::Put);
73        request.insert_header("x-ms-copy-action", "abort");
74        if let Some(lease_id) = options.lease_id.as_ref() {
75            request.insert_header("x-ms-lease-id", lease_id);
76        }
77        request.insert_header("x-ms-version", &self.version);
78        let rsp = self
79            .pipeline
80            .send(
81                &ctx,
82                &mut request,
83                Some(PipelineSendOptions {
84                    check_success: CheckSuccessOptions {
85                        success_codes: &[204],
86                    },
87                    ..Default::default()
88                }),
89            )
90            .await?;
91        Ok(rsp.into())
92    }
93
94    /// Requests a new lease on the specified blob.
95    ///
96    /// # Arguments
97    ///
98    /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A
99    ///   non-infinite lease can be between 15 and 60 seconds.
100    /// * `options` - Optional parameters for the request.
101    ///
102    /// ## Response Headers
103    ///
104    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientAcquireLeaseResultHeaders`] trait, which provides
105    /// access to response headers. For example:
106    ///
107    /// ```no_run
108    /// use azure_core::{Result, http::{Response, NoFormat}};
109    /// use azure_storage_blob::models::{BlobClientAcquireLeaseResult, BlobClientAcquireLeaseResultHeaders};
110    /// async fn example() -> Result<()> {
111    ///     let response: Response<BlobClientAcquireLeaseResult, NoFormat> = unimplemented!();
112    ///     // Access response headers
113    ///     if let Some(etag) = response.etag()? {
114    ///         println!("etag: {:?}", etag);
115    ///     }
116    ///     if let Some(last_modified) = response.last_modified()? {
117    ///         println!("last-modified: {:?}", last_modified);
118    ///     }
119    ///     if let Some(lease_id) = response.lease_id()? {
120    ///         println!("x-ms-lease-id: {:?}", lease_id);
121    ///     }
122    ///     Ok(())
123    /// }
124    /// ```
125    ///
126    /// ### Available headers
127    /// * [`etag`()](crate::generated::models::BlobClientAcquireLeaseResultHeaders::etag) - etag
128    /// * [`last_modified`()](crate::generated::models::BlobClientAcquireLeaseResultHeaders::last_modified) - last-modified
129    /// * [`lease_id`()](crate::generated::models::BlobClientAcquireLeaseResultHeaders::lease_id) - x-ms-lease-id
130    ///
131    /// [`BlobClientAcquireLeaseResultHeaders`]: crate::generated::models::BlobClientAcquireLeaseResultHeaders
132    #[tracing::function("Storage.Blob.BlobClient.acquireLease")]
133    pub async fn acquire_lease(
134        &self,
135        duration: i32,
136        options: Option<BlobClientAcquireLeaseOptions<'_>>,
137    ) -> Result<Response<BlobClientAcquireLeaseResult, NoFormat>> {
138        let options = options.unwrap_or_default();
139        let ctx = options.method_options.context.to_borrowed();
140        let mut url = self.endpoint.clone();
141        let mut query_builder = url.query_builder();
142        query_builder.append_pair("comp", "lease");
143        if let Some(timeout) = options.timeout {
144            query_builder.set_pair("timeout", timeout.to_string());
145        }
146        query_builder.build();
147        let mut request = Request::new(url, Method::Put);
148        if let Some(if_match) = options.if_match.as_ref() {
149            request.insert_header("if-match", if_match.to_string());
150        }
151        if let Some(if_modified_since) = options.if_modified_since {
152            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
153        }
154        if let Some(if_none_match) = options.if_none_match.as_ref() {
155            request.insert_header("if-none-match", if_none_match.to_string());
156        }
157        if let Some(if_unmodified_since) = options.if_unmodified_since {
158            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
159        }
160        if let Some(if_tags) = options.if_tags.as_ref() {
161            request.insert_header("x-ms-if-tags", if_tags);
162        }
163        request.insert_header("x-ms-lease-action", "acquire");
164        request.insert_header("x-ms-lease-duration", duration.to_string());
165        if let Some(proposed_lease_id) = options.proposed_lease_id.as_ref() {
166            request.insert_header("x-ms-proposed-lease-id", proposed_lease_id);
167        }
168        request.insert_header("x-ms-version", &self.version);
169        let rsp = self
170            .pipeline
171            .send(
172                &ctx,
173                &mut request,
174                Some(PipelineSendOptions {
175                    check_success: CheckSuccessOptions {
176                        success_codes: &[201],
177                    },
178                    ..Default::default()
179                }),
180            )
181            .await?;
182        Ok(rsp.into())
183    }
184
185    /// Ends a lease and ensures that another client can't acquire a new lease until the current lease period has expired.
186    ///
187    /// # Arguments
188    ///
189    /// * `options` - Optional parameters for the request.
190    ///
191    /// ## Response Headers
192    ///
193    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientBreakLeaseResultHeaders`] trait, which provides
194    /// access to response headers. For example:
195    ///
196    /// ```no_run
197    /// use azure_core::{Result, http::{Response, NoFormat}};
198    /// use azure_storage_blob::models::{BlobClientBreakLeaseResult, BlobClientBreakLeaseResultHeaders};
199    /// async fn example() -> Result<()> {
200    ///     let response: Response<BlobClientBreakLeaseResult, NoFormat> = unimplemented!();
201    ///     // Access response headers
202    ///     if let Some(etag) = response.etag()? {
203    ///         println!("etag: {:?}", etag);
204    ///     }
205    ///     if let Some(last_modified) = response.last_modified()? {
206    ///         println!("last-modified: {:?}", last_modified);
207    ///     }
208    ///     if let Some(lease_time) = response.lease_time()? {
209    ///         println!("x-ms-lease-time: {:?}", lease_time);
210    ///     }
211    ///     Ok(())
212    /// }
213    /// ```
214    ///
215    /// ### Available headers
216    /// * [`etag`()](crate::generated::models::BlobClientBreakLeaseResultHeaders::etag) - etag
217    /// * [`last_modified`()](crate::generated::models::BlobClientBreakLeaseResultHeaders::last_modified) - last-modified
218    /// * [`lease_time`()](crate::generated::models::BlobClientBreakLeaseResultHeaders::lease_time) - x-ms-lease-time
219    ///
220    /// [`BlobClientBreakLeaseResultHeaders`]: crate::generated::models::BlobClientBreakLeaseResultHeaders
221    #[tracing::function("Storage.Blob.BlobClient.breakLease")]
222    pub async fn break_lease(
223        &self,
224        options: Option<BlobClientBreakLeaseOptions<'_>>,
225    ) -> Result<Response<BlobClientBreakLeaseResult, NoFormat>> {
226        let options = options.unwrap_or_default();
227        let ctx = options.method_options.context.to_borrowed();
228        let mut url = self.endpoint.clone();
229        let mut query_builder = url.query_builder();
230        query_builder.append_pair("comp", "lease");
231        if let Some(timeout) = options.timeout {
232            query_builder.set_pair("timeout", timeout.to_string());
233        }
234        query_builder.build();
235        let mut request = Request::new(url, Method::Put);
236        if let Some(if_match) = options.if_match.as_ref() {
237            request.insert_header("if-match", if_match.to_string());
238        }
239        if let Some(if_modified_since) = options.if_modified_since {
240            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
241        }
242        if let Some(if_none_match) = options.if_none_match.as_ref() {
243            request.insert_header("if-none-match", if_none_match.to_string());
244        }
245        if let Some(if_unmodified_since) = options.if_unmodified_since {
246            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
247        }
248        if let Some(if_tags) = options.if_tags.as_ref() {
249            request.insert_header("x-ms-if-tags", if_tags);
250        }
251        request.insert_header("x-ms-lease-action", "break");
252        if let Some(break_period) = options.break_period {
253            request.insert_header("x-ms-lease-break-period", break_period.to_string());
254        }
255        request.insert_header("x-ms-version", &self.version);
256        let rsp = self
257            .pipeline
258            .send(
259                &ctx,
260                &mut request,
261                Some(PipelineSendOptions {
262                    check_success: CheckSuccessOptions {
263                        success_codes: &[202],
264                    },
265                    ..Default::default()
266                }),
267            )
268            .await?;
269        Ok(rsp.into())
270    }
271
272    /// Change the ID of an existing lease.
273    ///
274    /// # Arguments
275    ///
276    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
277    /// * `proposed_lease_id` - The proposed lease ID for the lease.
278    /// * `options` - Optional parameters for the request.
279    ///
280    /// ## Response Headers
281    ///
282    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientChangeLeaseResultHeaders`] trait, which provides
283    /// access to response headers. For example:
284    ///
285    /// ```no_run
286    /// use azure_core::{Result, http::{Response, NoFormat}};
287    /// use azure_storage_blob::models::{BlobClientChangeLeaseResult, BlobClientChangeLeaseResultHeaders};
288    /// async fn example() -> Result<()> {
289    ///     let response: Response<BlobClientChangeLeaseResult, NoFormat> = unimplemented!();
290    ///     // Access response headers
291    ///     if let Some(etag) = response.etag()? {
292    ///         println!("etag: {:?}", etag);
293    ///     }
294    ///     if let Some(last_modified) = response.last_modified()? {
295    ///         println!("last-modified: {:?}", last_modified);
296    ///     }
297    ///     if let Some(lease_id) = response.lease_id()? {
298    ///         println!("x-ms-lease-id: {:?}", lease_id);
299    ///     }
300    ///     Ok(())
301    /// }
302    /// ```
303    ///
304    /// ### Available headers
305    /// * [`etag`()](crate::generated::models::BlobClientChangeLeaseResultHeaders::etag) - etag
306    /// * [`last_modified`()](crate::generated::models::BlobClientChangeLeaseResultHeaders::last_modified) - last-modified
307    /// * [`lease_id`()](crate::generated::models::BlobClientChangeLeaseResultHeaders::lease_id) - x-ms-lease-id
308    ///
309    /// [`BlobClientChangeLeaseResultHeaders`]: crate::generated::models::BlobClientChangeLeaseResultHeaders
310    #[tracing::function("Storage.Blob.BlobClient.changeLease")]
311    pub async fn change_lease(
312        &self,
313        lease_id: String,
314        proposed_lease_id: String,
315        options: Option<BlobClientChangeLeaseOptions<'_>>,
316    ) -> Result<Response<BlobClientChangeLeaseResult, NoFormat>> {
317        let options = options.unwrap_or_default();
318        let ctx = options.method_options.context.to_borrowed();
319        let mut url = self.endpoint.clone();
320        let mut query_builder = url.query_builder();
321        query_builder.append_pair("comp", "lease");
322        if let Some(timeout) = options.timeout {
323            query_builder.set_pair("timeout", timeout.to_string());
324        }
325        query_builder.build();
326        let mut request = Request::new(url, Method::Put);
327        if let Some(if_match) = options.if_match.as_ref() {
328            request.insert_header("if-match", if_match.to_string());
329        }
330        if let Some(if_modified_since) = options.if_modified_since {
331            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
332        }
333        if let Some(if_none_match) = options.if_none_match.as_ref() {
334            request.insert_header("if-none-match", if_none_match.to_string());
335        }
336        if let Some(if_unmodified_since) = options.if_unmodified_since {
337            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
338        }
339        if let Some(if_tags) = options.if_tags.as_ref() {
340            request.insert_header("x-ms-if-tags", if_tags);
341        }
342        request.insert_header("x-ms-lease-action", "change");
343        request.insert_header("x-ms-lease-id", lease_id);
344        request.insert_header("x-ms-proposed-lease-id", proposed_lease_id);
345        request.insert_header("x-ms-version", &self.version);
346        let rsp = self
347            .pipeline
348            .send(
349                &ctx,
350                &mut request,
351                Some(PipelineSendOptions {
352                    check_success: CheckSuccessOptions {
353                        success_codes: &[200],
354                    },
355                    ..Default::default()
356                }),
357            )
358            .await?;
359        Ok(rsp.into())
360    }
361
362    /// Creates a read-only snapshot of the specified blob.
363    ///
364    /// # Arguments
365    ///
366    /// * `options` - Optional parameters for the request.
367    ///
368    /// ## Response Headers
369    ///
370    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientCreateSnapshotResultHeaders`] trait, which provides
371    /// access to response headers. For example:
372    ///
373    /// ```no_run
374    /// use azure_core::{Result, http::{Response, NoFormat}};
375    /// use azure_storage_blob::models::{BlobClientCreateSnapshotResult, BlobClientCreateSnapshotResultHeaders};
376    /// async fn example() -> Result<()> {
377    ///     let response: Response<BlobClientCreateSnapshotResult, NoFormat> = unimplemented!();
378    ///     // Access response headers
379    ///     if let Some(etag) = response.etag()? {
380    ///         println!("etag: {:?}", etag);
381    ///     }
382    ///     if let Some(last_modified) = response.last_modified()? {
383    ///         println!("last-modified: {:?}", last_modified);
384    ///     }
385    ///     if let Some(is_server_encrypted) = response.is_server_encrypted()? {
386    ///         println!("x-ms-request-server-encrypted: {:?}", is_server_encrypted);
387    ///     }
388    ///     Ok(())
389    /// }
390    /// ```
391    ///
392    /// ### Available headers
393    /// * [`etag`()](crate::generated::models::BlobClientCreateSnapshotResultHeaders::etag) - etag
394    /// * [`last_modified`()](crate::generated::models::BlobClientCreateSnapshotResultHeaders::last_modified) - last-modified
395    /// * [`is_server_encrypted`()](crate::generated::models::BlobClientCreateSnapshotResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
396    /// * [`snapshot`()](crate::generated::models::BlobClientCreateSnapshotResultHeaders::snapshot) - x-ms-snapshot
397    /// * [`version_id`()](crate::generated::models::BlobClientCreateSnapshotResultHeaders::version_id) - x-ms-version-id
398    ///
399    /// [`BlobClientCreateSnapshotResultHeaders`]: crate::generated::models::BlobClientCreateSnapshotResultHeaders
400    #[tracing::function("Storage.Blob.BlobClient.createSnapshot")]
401    pub async fn create_snapshot(
402        &self,
403        options: Option<BlobClientCreateSnapshotOptions<'_>>,
404    ) -> Result<Response<BlobClientCreateSnapshotResult, NoFormat>> {
405        let options = options.unwrap_or_default();
406        let ctx = options.method_options.context.to_borrowed();
407        let mut url = self.endpoint.clone();
408        let mut query_builder = url.query_builder();
409        query_builder.append_pair("comp", "snapshot");
410        if let Some(timeout) = options.timeout {
411            query_builder.set_pair("timeout", timeout.to_string());
412        }
413        query_builder.build();
414        let mut request = Request::new(url, Method::Put);
415        if let Some(if_match) = options.if_match.as_ref() {
416            request.insert_header("if-match", if_match.to_string());
417        }
418        if let Some(if_modified_since) = options.if_modified_since {
419            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
420        }
421        if let Some(if_none_match) = options.if_none_match.as_ref() {
422            request.insert_header("if-none-match", if_none_match.to_string());
423        }
424        if let Some(if_unmodified_since) = options.if_unmodified_since {
425            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
426        }
427        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
428            request.insert_header(
429                "x-ms-encryption-algorithm",
430                encryption_algorithm.to_string(),
431            );
432        }
433        if let Some(encryption_key) = options.encryption_key.as_ref() {
434            request.insert_header("x-ms-encryption-key", encryption_key);
435        }
436        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
437            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
438        }
439        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
440            request.insert_header("x-ms-encryption-scope", encryption_scope);
441        }
442        if let Some(if_tags) = options.if_tags.as_ref() {
443            request.insert_header("x-ms-if-tags", if_tags);
444        }
445        if let Some(lease_id) = options.lease_id.as_ref() {
446            request.insert_header("x-ms-lease-id", lease_id);
447        }
448        if let Some(metadata) = options.metadata.as_ref() {
449            for (k, v) in metadata {
450                request.insert_header(format!("x-ms-meta-{k}"), v);
451            }
452        }
453        request.insert_header("x-ms-version", &self.version);
454        let rsp = self
455            .pipeline
456            .send(
457                &ctx,
458                &mut request,
459                Some(PipelineSendOptions {
460                    check_success: CheckSuccessOptions {
461                        success_codes: &[201],
462                    },
463                    ..Default::default()
464                }),
465            )
466            .await?;
467        Ok(rsp.into())
468    }
469
470    /// Deletes the specified blob. If blob soft delete is enabled, the blob is marked for deletion and can be recovered until
471    /// the retention period expires.
472    ///
473    /// # Arguments
474    ///
475    /// * `options` - Optional parameters for the request.
476    #[tracing::function("Storage.Blob.BlobClient.delete")]
477    pub async fn delete(
478        &self,
479        options: Option<BlobClientDeleteOptions<'_>>,
480    ) -> Result<Response<(), NoFormat>> {
481        let options = options.unwrap_or_default();
482        let ctx = options.method_options.context.to_borrowed();
483        let mut url = self.endpoint.clone();
484        let mut query_builder = url.query_builder();
485        if let Some(blob_delete_type) = options.blob_delete_type.as_ref() {
486            query_builder.set_pair("deletetype", blob_delete_type.as_ref());
487        }
488        if let Some(snapshot) = options.snapshot.as_ref() {
489            query_builder.set_pair("snapshot", snapshot);
490        }
491        if let Some(timeout) = options.timeout {
492            query_builder.set_pair("timeout", timeout.to_string());
493        }
494        if let Some(version_id) = options.version_id.as_ref() {
495            query_builder.set_pair("versionid", version_id);
496        }
497        query_builder.build();
498        let mut request = Request::new(url, Method::Delete);
499        if let Some(if_match) = options.if_match.as_ref() {
500            request.insert_header("if-match", if_match.to_string());
501        }
502        if let Some(if_modified_since) = options.if_modified_since {
503            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
504        }
505        if let Some(if_none_match) = options.if_none_match.as_ref() {
506            request.insert_header("if-none-match", if_none_match.to_string());
507        }
508        if let Some(if_unmodified_since) = options.if_unmodified_since {
509            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
510        }
511        if let Some(access_tier_if_modified_since) = options.access_tier_if_modified_since {
512            request.insert_header(
513                "x-ms-access-tier-if-modified-since",
514                to_rfc7231(&access_tier_if_modified_since),
515            );
516        }
517        if let Some(access_tier_if_unmodified_since) = options.access_tier_if_unmodified_since {
518            request.insert_header(
519                "x-ms-access-tier-if-unmodified-since",
520                to_rfc7231(&access_tier_if_unmodified_since),
521            );
522        }
523        if let Some(delete_snapshots) = options.delete_snapshots.as_ref() {
524            request.insert_header("x-ms-delete-snapshots", delete_snapshots.to_string());
525        }
526        if let Some(if_tags) = options.if_tags.as_ref() {
527            request.insert_header("x-ms-if-tags", if_tags);
528        }
529        if let Some(lease_id) = options.lease_id.as_ref() {
530            request.insert_header("x-ms-lease-id", lease_id);
531        }
532        request.insert_header("x-ms-version", &self.version);
533        let rsp = self
534            .pipeline
535            .send(
536                &ctx,
537                &mut request,
538                Some(PipelineSendOptions {
539                    check_success: CheckSuccessOptions {
540                        success_codes: &[202],
541                    },
542                    ..Default::default()
543                }),
544            )
545            .await?;
546        Ok(rsp.into())
547    }
548
549    /// Deletes the immutability policy on the specified blob.
550    ///
551    /// # Arguments
552    ///
553    /// * `options` - Optional parameters for the request.
554    #[tracing::function("Storage.Blob.BlobClient.deleteImmutabilityPolicy")]
555    pub async fn delete_immutability_policy(
556        &self,
557        options: Option<BlobClientDeleteImmutabilityPolicyOptions<'_>>,
558    ) -> Result<Response<(), NoFormat>> {
559        let options = options.unwrap_or_default();
560        let ctx = options.method_options.context.to_borrowed();
561        let mut url = self.endpoint.clone();
562        let mut query_builder = url.query_builder();
563        query_builder.append_pair("comp", "immutabilityPolicies");
564        if let Some(snapshot) = options.snapshot.as_ref() {
565            query_builder.set_pair("snapshot", snapshot);
566        }
567        if let Some(timeout) = options.timeout {
568            query_builder.set_pair("timeout", timeout.to_string());
569        }
570        if let Some(version_id) = options.version_id.as_ref() {
571            query_builder.set_pair("versionid", version_id);
572        }
573        query_builder.build();
574        let mut request = Request::new(url, Method::Delete);
575        request.insert_header("x-ms-version", &self.version);
576        let rsp = self
577            .pipeline
578            .send(
579                &ctx,
580                &mut request,
581                Some(PipelineSendOptions {
582                    check_success: CheckSuccessOptions {
583                        success_codes: &[200],
584                    },
585                    ..Default::default()
586                }),
587            )
588            .await?;
589        Ok(rsp.into())
590    }
591
592    /// Downloads the specified blob.
593    ///
594    /// # Arguments
595    ///
596    /// * `options` - Optional parameters for the request.
597    ///
598    /// ## Response Headers
599    ///
600    /// The returned [`AsyncResponse`](azure_core::http::AsyncResponse) implements the [`BlobClientDownloadInternalResultHeaders`] trait, which provides
601    /// access to response headers. For example:
602    ///
603    /// ```ignore
604    /// use azure_core::{Result, http::AsyncResponse};
605    /// use azure_storage_blob::models::{BlobClientDownloadInternalResult, BlobClientDownloadInternalResultHeaders};
606    /// async fn example() -> Result<()> {
607    ///     let response: AsyncResponse<BlobClientDownloadInternalResult> = unimplemented!();
608    ///     // Access response headers
609    ///     if let Some(cache_control) = response.cache_control()? {
610    ///         println!("cache-control: {:?}", cache_control);
611    ///     }
612    ///     if let Some(content_disposition) = response.content_disposition()? {
613    ///         println!("content-disposition: {:?}", content_disposition);
614    ///     }
615    ///     if let Some(content_encoding) = response.content_encoding()? {
616    ///         println!("content-encoding: {:?}", content_encoding);
617    ///     }
618    ///     Ok(())
619    /// }
620    /// ```
621    ///
622    /// ### Available headers
623    /// * [`cache_control`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::cache_control) - cache-control
624    /// * [`content_disposition`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_disposition) - content-disposition
625    /// * [`content_encoding`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_encoding) - content-encoding
626    /// * [`content_language`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_language) - content-language
627    /// * [`content_length`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_length) - content-length
628    /// * [`content_md5`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_md5) - content-md5
629    /// * [`content_range`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_range) - content-range
630    /// * [`etag`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::etag) - etag
631    /// * [`last_modified`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::last_modified) - last-modified
632    /// * [`blob_committed_block_count`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::blob_committed_block_count) - x-ms-blob-committed-block-count
633    /// * [`blob_content_md5`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::blob_content_md5) - x-ms-blob-content-md5
634    /// * [`is_sealed`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::is_sealed) - x-ms-blob-sealed
635    /// * [`blob_sequence_number`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::blob_sequence_number) - x-ms-blob-sequence-number
636    /// * [`blob_type`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::blob_type) - x-ms-blob-type
637    /// * [`content_crc64`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::content_crc64) - x-ms-content-crc64
638    /// * [`copy_completion_time`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_completion_time) - x-ms-copy-completion-time
639    /// * [`copy_id`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_id) - x-ms-copy-id
640    /// * [`copy_progress`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_progress) - x-ms-copy-progress
641    /// * [`copy_source`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_source) - x-ms-copy-source
642    /// * [`copy_status`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_status) - x-ms-copy-status
643    /// * [`copy_status_description`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::copy_status_description) - x-ms-copy-status-description
644    /// * [`creation_time`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::creation_time) - x-ms-creation-time
645    /// * [`encryption_key_sha256`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
646    /// * [`encryption_scope`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::encryption_scope) - x-ms-encryption-scope
647    /// * [`immutability_policy_mode`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::immutability_policy_mode) - x-ms-immutability-policy-mode
648    /// * [`immutability_policy_expires_on`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::immutability_policy_expires_on) - x-ms-immutability-policy-until-date
649    /// * [`is_current_version`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::is_current_version) - x-ms-is-current-version
650    /// * [`last_accessed`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::last_accessed) - x-ms-last-access-time
651    /// * [`duration`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::duration) - x-ms-lease-duration
652    /// * [`lease_state`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::lease_state) - x-ms-lease-state
653    /// * [`lease_status`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::lease_status) - x-ms-lease-status
654    /// * [`legal_hold`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::legal_hold) - x-ms-legal-hold
655    /// * [`metadata`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::metadata) - x-ms-meta
656    /// * [`object_replication_rules`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::object_replication_rules) - x-ms-or
657    /// * [`object_replication_policy_id`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::object_replication_policy_id) - x-ms-or-policy-id
658    /// * [`is_server_encrypted`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::is_server_encrypted) - x-ms-server-encrypted
659    /// * [`tag_count`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::tag_count) - x-ms-tag-count
660    /// * [`version_id`()](crate::generated::models::BlobClientDownloadInternalResultHeaders::version_id) - x-ms-version-id
661    ///
662    /// [`BlobClientDownloadInternalResultHeaders`]: crate::generated::models::BlobClientDownloadInternalResultHeaders
663    #[tracing::function("Storage.Blob.BlobClient.download")]
664    pub(crate) async fn download_internal(
665        &self,
666        options: Option<BlobClientDownloadInternalOptions<'_>>,
667    ) -> Result<AsyncResponse<BlobClientDownloadInternalResult>> {
668        let options = options.unwrap_or_default();
669        let ctx = options.method_options.context.to_borrowed();
670        let mut url = self.endpoint.clone();
671        let mut query_builder = url.query_builder();
672        if let Some(snapshot) = options.snapshot.as_ref() {
673            query_builder.set_pair("snapshot", snapshot);
674        }
675        if let Some(timeout) = options.timeout {
676            query_builder.set_pair("timeout", timeout.to_string());
677        }
678        if let Some(version_id) = options.version_id.as_ref() {
679            query_builder.set_pair("versionid", version_id);
680        }
681        query_builder.build();
682        let mut request = Request::new(url, Method::Get);
683        request.insert_header("accept", "application/octet-stream");
684        if let Some(if_match) = options.if_match.as_ref() {
685            request.insert_header("if-match", if_match.to_string());
686        }
687        if let Some(if_modified_since) = options.if_modified_since {
688            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
689        }
690        if let Some(if_none_match) = options.if_none_match.as_ref() {
691            request.insert_header("if-none-match", if_none_match.to_string());
692        }
693        if let Some(if_unmodified_since) = options.if_unmodified_since {
694            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
695        }
696        if let Some(range) = options.range.as_ref() {
697            request.insert_header("range", range.to_string());
698        }
699        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
700            request.insert_header(
701                "x-ms-encryption-algorithm",
702                encryption_algorithm.to_string(),
703            );
704        }
705        if let Some(encryption_key) = options.encryption_key.as_ref() {
706            request.insert_header("x-ms-encryption-key", encryption_key);
707        }
708        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
709            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
710        }
711        if let Some(if_tags) = options.if_tags.as_ref() {
712            request.insert_header("x-ms-if-tags", if_tags);
713        }
714        if let Some(lease_id) = options.lease_id.as_ref() {
715            request.insert_header("x-ms-lease-id", lease_id);
716        }
717        if let Some(range_get_content_crc64) = options.range_get_content_crc64 {
718            request.insert_header(
719                "x-ms-range-get-content-crc64",
720                range_get_content_crc64.to_string(),
721            );
722        }
723        if let Some(range_get_content_md5) = options.range_get_content_md5 {
724            request.insert_header(
725                "x-ms-range-get-content-md5",
726                range_get_content_md5.to_string(),
727            );
728        }
729        if let Some(structured_body_type) = options.structured_body_type.as_ref() {
730            request.insert_header("x-ms-structured-body", structured_body_type);
731        }
732        request.insert_header("x-ms-version", &self.version);
733        let rsp = self
734            .pipeline
735            .stream(
736                &ctx,
737                &mut request,
738                Some(PipelineStreamOptions {
739                    check_success: CheckSuccessOptions {
740                        success_codes: &[200, 206],
741                    },
742                    ..Default::default()
743                }),
744            )
745            .await?;
746        Ok(rsp.into())
747    }
748
749    /// Returns information about the storage account.
750    ///
751    /// # Arguments
752    ///
753    /// * `options` - Optional parameters for the request.
754    ///
755    /// ## Response Headers
756    ///
757    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientGetAccountInfoResultHeaders`] trait, which provides
758    /// access to response headers. For example:
759    ///
760    /// ```no_run
761    /// use azure_core::{Result, http::{Response, NoFormat}};
762    /// use azure_storage_blob::models::{BlobClientGetAccountInfoResult, BlobClientGetAccountInfoResultHeaders};
763    /// async fn example() -> Result<()> {
764    ///     let response: Response<BlobClientGetAccountInfoResult, NoFormat> = unimplemented!();
765    ///     // Access response headers
766    ///     if let Some(account_kind) = response.account_kind()? {
767    ///         println!("x-ms-account-kind: {:?}", account_kind);
768    ///     }
769    ///     if let Some(is_hierarchical_namespace_enabled) = response.is_hierarchical_namespace_enabled()? {
770    ///         println!("x-ms-is-hns-enabled: {:?}", is_hierarchical_namespace_enabled);
771    ///     }
772    ///     if let Some(sku_name) = response.sku_name()? {
773    ///         println!("x-ms-sku-name: {:?}", sku_name);
774    ///     }
775    ///     Ok(())
776    /// }
777    /// ```
778    ///
779    /// ### Available headers
780    /// * [`account_kind`()](crate::generated::models::BlobClientGetAccountInfoResultHeaders::account_kind) - x-ms-account-kind
781    /// * [`is_hierarchical_namespace_enabled`()](crate::generated::models::BlobClientGetAccountInfoResultHeaders::is_hierarchical_namespace_enabled) - x-ms-is-hns-enabled
782    /// * [`sku_name`()](crate::generated::models::BlobClientGetAccountInfoResultHeaders::sku_name) - x-ms-sku-name
783    ///
784    /// [`BlobClientGetAccountInfoResultHeaders`]: crate::generated::models::BlobClientGetAccountInfoResultHeaders
785    #[tracing::function("Storage.Blob.BlobClient.getAccountInfo")]
786    pub async fn get_account_info(
787        &self,
788        options: Option<BlobClientGetAccountInfoOptions<'_>>,
789    ) -> Result<Response<BlobClientGetAccountInfoResult, NoFormat>> {
790        let options = options.unwrap_or_default();
791        let ctx = options.method_options.context.to_borrowed();
792        let mut url = self.endpoint.clone();
793        let mut query_builder = url.query_builder();
794        query_builder
795            .append_pair("comp", "properties")
796            .append_pair("restype", "account");
797        if let Some(timeout) = options.timeout {
798            query_builder.set_pair("timeout", timeout.to_string());
799        }
800        query_builder.build();
801        let mut request = Request::new(url, Method::Get);
802        request.insert_header("x-ms-version", &self.version);
803        let rsp = self
804            .pipeline
805            .send(
806                &ctx,
807                &mut request,
808                Some(PipelineSendOptions {
809                    check_success: CheckSuccessOptions {
810                        success_codes: &[200],
811                    },
812                    ..Default::default()
813                }),
814            )
815            .await?;
816        Ok(rsp.into())
817    }
818
819    /// Returns all user-defined metadata, standard HTTP properties, and system properties for the specified blob. It does not
820    /// return the content of the blob.
821    ///
822    /// # Arguments
823    ///
824    /// * `options` - Optional parameters for the request.
825    ///
826    /// ## Response Headers
827    ///
828    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientGetPropertiesResultHeaders`] trait, which provides
829    /// access to response headers. For example:
830    ///
831    /// ```no_run
832    /// use azure_core::{Result, http::{Response, NoFormat}};
833    /// use azure_storage_blob::models::{BlobClientGetPropertiesResult, BlobClientGetPropertiesResultHeaders};
834    /// async fn example() -> Result<()> {
835    ///     let response: Response<BlobClientGetPropertiesResult, NoFormat> = unimplemented!();
836    ///     // Access response headers
837    ///     if let Some(cache_control) = response.cache_control()? {
838    ///         println!("cache-control: {:?}", cache_control);
839    ///     }
840    ///     if let Some(content_disposition) = response.content_disposition()? {
841    ///         println!("content-disposition: {:?}", content_disposition);
842    ///     }
843    ///     if let Some(content_encoding) = response.content_encoding()? {
844    ///         println!("content-encoding: {:?}", content_encoding);
845    ///     }
846    ///     Ok(())
847    /// }
848    /// ```
849    ///
850    /// ### Available headers
851    /// * [`cache_control`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::cache_control) - cache-control
852    /// * [`content_disposition`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_disposition) - content-disposition
853    /// * [`content_encoding`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_encoding) - content-encoding
854    /// * [`content_language`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_language) - content-language
855    /// * [`content_length`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_length) - content-length
856    /// * [`content_md5`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_md5) - content-md5
857    /// * [`content_type`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::content_type) - content-type
858    /// * [`etag`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::etag) - etag
859    /// * [`last_modified`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::last_modified) - last-modified
860    /// * [`access_tier`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::access_tier) - x-ms-access-tier
861    /// * [`access_tier_change_time`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::access_tier_change_time) - x-ms-access-tier-change-time
862    /// * [`access_tier_inferred`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::access_tier_inferred) - x-ms-access-tier-inferred
863    /// * [`archive_status`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::archive_status) - x-ms-archive-status
864    /// * [`blob_committed_block_count`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::blob_committed_block_count) - x-ms-blob-committed-block-count
865    /// * [`is_sealed`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::is_sealed) - x-ms-blob-sealed
866    /// * [`blob_sequence_number`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::blob_sequence_number) - x-ms-blob-sequence-number
867    /// * [`blob_type`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::blob_type) - x-ms-blob-type
868    /// * [`copy_completion_time`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_completion_time) - x-ms-copy-completion-time
869    /// * [`destination_snapshot`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::destination_snapshot) - x-ms-copy-destination-snapshot
870    /// * [`copy_id`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_id) - x-ms-copy-id
871    /// * [`copy_progress`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_progress) - x-ms-copy-progress
872    /// * [`copy_source`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_source) - x-ms-copy-source
873    /// * [`copy_status`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_status) - x-ms-copy-status
874    /// * [`copy_status_description`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::copy_status_description) - x-ms-copy-status-description
875    /// * [`creation_time`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::creation_time) - x-ms-creation-time
876    /// * [`encryption_key_sha256`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
877    /// * [`encryption_scope`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::encryption_scope) - x-ms-encryption-scope
878    /// * [`expires_on`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::expires_on) - x-ms-expiry-time
879    /// * [`immutability_policy_mode`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::immutability_policy_mode) - x-ms-immutability-policy-mode
880    /// * [`immutability_policy_expires_on`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::immutability_policy_expires_on) - x-ms-immutability-policy-until-date
881    /// * [`is_incremental_copy`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::is_incremental_copy) - x-ms-incremental-copy
882    /// * [`is_current_version`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::is_current_version) - x-ms-is-current-version
883    /// * [`last_accessed`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::last_accessed) - x-ms-last-access-time
884    /// * [`duration`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::duration) - x-ms-lease-duration
885    /// * [`lease_state`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::lease_state) - x-ms-lease-state
886    /// * [`lease_status`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::lease_status) - x-ms-lease-status
887    /// * [`legal_hold`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::legal_hold) - x-ms-legal-hold
888    /// * [`metadata`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::metadata) - x-ms-meta
889    /// * [`object_replication_rules`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::object_replication_rules) - x-ms-or
890    /// * [`object_replication_policy_id`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::object_replication_policy_id) - x-ms-or-policy-id
891    /// * [`rehydrate_priority`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::rehydrate_priority) - x-ms-rehydrate-priority
892    /// * [`is_server_encrypted`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::is_server_encrypted) - x-ms-server-encrypted
893    /// * [`tag_count`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::tag_count) - x-ms-tag-count
894    /// * [`version_id`()](crate::generated::models::BlobClientGetPropertiesResultHeaders::version_id) - x-ms-version-id
895    ///
896    /// [`BlobClientGetPropertiesResultHeaders`]: crate::generated::models::BlobClientGetPropertiesResultHeaders
897    #[tracing::function("Storage.Blob.BlobClient.getProperties")]
898    pub async fn get_properties(
899        &self,
900        options: Option<BlobClientGetPropertiesOptions<'_>>,
901    ) -> Result<Response<BlobClientGetPropertiesResult, NoFormat>> {
902        let options = options.unwrap_or_default();
903        let ctx = options.method_options.context.to_borrowed();
904        let mut url = self.endpoint.clone();
905        let mut query_builder = url.query_builder();
906        if let Some(snapshot) = options.snapshot.as_ref() {
907            query_builder.set_pair("snapshot", snapshot);
908        }
909        if let Some(timeout) = options.timeout {
910            query_builder.set_pair("timeout", timeout.to_string());
911        }
912        if let Some(version_id) = options.version_id.as_ref() {
913            query_builder.set_pair("versionid", version_id);
914        }
915        query_builder.build();
916        let mut request = Request::new(url, Method::Head);
917        if let Some(if_match) = options.if_match.as_ref() {
918            request.insert_header("if-match", if_match.to_string());
919        }
920        if let Some(if_modified_since) = options.if_modified_since {
921            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
922        }
923        if let Some(if_none_match) = options.if_none_match.as_ref() {
924            request.insert_header("if-none-match", if_none_match.to_string());
925        }
926        if let Some(if_unmodified_since) = options.if_unmodified_since {
927            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
928        }
929        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
930            request.insert_header(
931                "x-ms-encryption-algorithm",
932                encryption_algorithm.to_string(),
933            );
934        }
935        if let Some(encryption_key) = options.encryption_key.as_ref() {
936            request.insert_header("x-ms-encryption-key", encryption_key);
937        }
938        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
939            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
940        }
941        if let Some(if_tags) = options.if_tags.as_ref() {
942            request.insert_header("x-ms-if-tags", if_tags);
943        }
944        if let Some(lease_id) = options.lease_id.as_ref() {
945            request.insert_header("x-ms-lease-id", lease_id);
946        }
947        request.insert_header("x-ms-version", &self.version);
948        let rsp = self
949            .pipeline
950            .send(
951                &ctx,
952                &mut request,
953                Some(PipelineSendOptions {
954                    check_success: CheckSuccessOptions {
955                        success_codes: &[200],
956                    },
957                    ..Default::default()
958                }),
959            )
960            .await?;
961        Ok(rsp.into())
962    }
963
964    /// Gets the tags of the specified blob.
965    ///
966    /// # Arguments
967    ///
968    /// * `options` - Optional parameters for the request.
969    #[tracing::function("Storage.Blob.BlobClient.getTags")]
970    pub async fn get_tags(
971        &self,
972        options: Option<BlobClientGetTagsOptions<'_>>,
973    ) -> Result<Response<BlobTags, XmlFormat>> {
974        let options = options.unwrap_or_default();
975        let ctx = options.method_options.context.to_borrowed();
976        let mut url = self.endpoint.clone();
977        let mut query_builder = url.query_builder();
978        query_builder.append_pair("comp", "tags");
979        if let Some(snapshot) = options.snapshot.as_ref() {
980            query_builder.set_pair("snapshot", snapshot);
981        }
982        if let Some(timeout) = options.timeout {
983            query_builder.set_pair("timeout", timeout.to_string());
984        }
985        if let Some(version_id) = options.version_id.as_ref() {
986            query_builder.set_pair("versionid", version_id);
987        }
988        query_builder.build();
989        let mut request = Request::new(url, Method::Get);
990        request.insert_header("accept", "application/xml");
991        if let Some(if_match) = options.if_match.as_ref() {
992            request.insert_header("x-ms-blob-if-match", if_match.to_string());
993        }
994        if let Some(if_modified_since) = options.if_modified_since {
995            request.insert_header(
996                "x-ms-blob-if-modified-since",
997                to_rfc7231(&if_modified_since),
998            );
999        }
1000        if let Some(if_none_match) = options.if_none_match.as_ref() {
1001            request.insert_header("x-ms-blob-if-none-match", if_none_match.to_string());
1002        }
1003        if let Some(if_unmodified_since) = options.if_unmodified_since {
1004            request.insert_header(
1005                "x-ms-blob-if-unmodified-since",
1006                to_rfc7231(&if_unmodified_since),
1007            );
1008        }
1009        if let Some(if_tags) = options.if_tags.as_ref() {
1010            request.insert_header("x-ms-if-tags", if_tags);
1011        }
1012        if let Some(lease_id) = options.lease_id.as_ref() {
1013            request.insert_header("x-ms-lease-id", lease_id);
1014        }
1015        request.insert_header("x-ms-version", &self.version);
1016        let rsp = self
1017            .pipeline
1018            .send(
1019                &ctx,
1020                &mut request,
1021                Some(PipelineSendOptions {
1022                    check_success: CheckSuccessOptions {
1023                        success_codes: &[200],
1024                    },
1025                    ..Default::default()
1026                }),
1027            )
1028            .await?;
1029        Ok(rsp.into())
1030    }
1031
1032    /// Frees the lease if it's no longer needed, so that another client can immediately acquire a lease against the blob.
1033    ///
1034    /// # Arguments
1035    ///
1036    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
1037    /// * `options` - Optional parameters for the request.
1038    ///
1039    /// ## Response Headers
1040    ///
1041    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientReleaseLeaseResultHeaders`] trait, which provides
1042    /// access to response headers. For example:
1043    ///
1044    /// ```no_run
1045    /// use azure_core::{Result, http::{Response, NoFormat}};
1046    /// use azure_storage_blob::models::{BlobClientReleaseLeaseResult, BlobClientReleaseLeaseResultHeaders};
1047    /// async fn example() -> Result<()> {
1048    ///     let response: Response<BlobClientReleaseLeaseResult, NoFormat> = unimplemented!();
1049    ///     // Access response headers
1050    ///     if let Some(etag) = response.etag()? {
1051    ///         println!("etag: {:?}", etag);
1052    ///     }
1053    ///     if let Some(last_modified) = response.last_modified()? {
1054    ///         println!("last-modified: {:?}", last_modified);
1055    ///     }
1056    ///     Ok(())
1057    /// }
1058    /// ```
1059    ///
1060    /// ### Available headers
1061    /// * [`etag`()](crate::generated::models::BlobClientReleaseLeaseResultHeaders::etag) - etag
1062    /// * [`last_modified`()](crate::generated::models::BlobClientReleaseLeaseResultHeaders::last_modified) - last-modified
1063    ///
1064    /// [`BlobClientReleaseLeaseResultHeaders`]: crate::generated::models::BlobClientReleaseLeaseResultHeaders
1065    #[tracing::function("Storage.Blob.BlobClient.releaseLease")]
1066    pub async fn release_lease(
1067        &self,
1068        lease_id: String,
1069        options: Option<BlobClientReleaseLeaseOptions<'_>>,
1070    ) -> Result<Response<BlobClientReleaseLeaseResult, NoFormat>> {
1071        let options = options.unwrap_or_default();
1072        let ctx = options.method_options.context.to_borrowed();
1073        let mut url = self.endpoint.clone();
1074        let mut query_builder = url.query_builder();
1075        query_builder.append_pair("comp", "lease");
1076        if let Some(timeout) = options.timeout {
1077            query_builder.set_pair("timeout", timeout.to_string());
1078        }
1079        query_builder.build();
1080        let mut request = Request::new(url, Method::Put);
1081        if let Some(if_match) = options.if_match.as_ref() {
1082            request.insert_header("if-match", if_match.to_string());
1083        }
1084        if let Some(if_modified_since) = options.if_modified_since {
1085            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1086        }
1087        if let Some(if_none_match) = options.if_none_match.as_ref() {
1088            request.insert_header("if-none-match", if_none_match.to_string());
1089        }
1090        if let Some(if_unmodified_since) = options.if_unmodified_since {
1091            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1092        }
1093        if let Some(if_tags) = options.if_tags.as_ref() {
1094            request.insert_header("x-ms-if-tags", if_tags);
1095        }
1096        request.insert_header("x-ms-lease-action", "release");
1097        request.insert_header("x-ms-lease-id", lease_id);
1098        request.insert_header("x-ms-version", &self.version);
1099        let rsp = self
1100            .pipeline
1101            .send(
1102                &ctx,
1103                &mut request,
1104                Some(PipelineSendOptions {
1105                    check_success: CheckSuccessOptions {
1106                        success_codes: &[200],
1107                    },
1108                    ..Default::default()
1109                }),
1110            )
1111            .await?;
1112        Ok(rsp.into())
1113    }
1114
1115    /// Renews an existing lease.
1116    ///
1117    /// # Arguments
1118    ///
1119    /// * `lease_id` - A lease ID for the resource. The resource must have an active lease and the lease ID must match.
1120    /// * `options` - Optional parameters for the request.
1121    ///
1122    /// ## Response Headers
1123    ///
1124    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientRenewLeaseResultHeaders`] trait, which provides
1125    /// access to response headers. For example:
1126    ///
1127    /// ```no_run
1128    /// use azure_core::{Result, http::{Response, NoFormat}};
1129    /// use azure_storage_blob::models::{BlobClientRenewLeaseResult, BlobClientRenewLeaseResultHeaders};
1130    /// async fn example() -> Result<()> {
1131    ///     let response: Response<BlobClientRenewLeaseResult, NoFormat> = unimplemented!();
1132    ///     // Access response headers
1133    ///     if let Some(etag) = response.etag()? {
1134    ///         println!("etag: {:?}", etag);
1135    ///     }
1136    ///     if let Some(last_modified) = response.last_modified()? {
1137    ///         println!("last-modified: {:?}", last_modified);
1138    ///     }
1139    ///     if let Some(lease_id) = response.lease_id()? {
1140    ///         println!("x-ms-lease-id: {:?}", lease_id);
1141    ///     }
1142    ///     Ok(())
1143    /// }
1144    /// ```
1145    ///
1146    /// ### Available headers
1147    /// * [`etag`()](crate::generated::models::BlobClientRenewLeaseResultHeaders::etag) - etag
1148    /// * [`last_modified`()](crate::generated::models::BlobClientRenewLeaseResultHeaders::last_modified) - last-modified
1149    /// * [`lease_id`()](crate::generated::models::BlobClientRenewLeaseResultHeaders::lease_id) - x-ms-lease-id
1150    ///
1151    /// [`BlobClientRenewLeaseResultHeaders`]: crate::generated::models::BlobClientRenewLeaseResultHeaders
1152    #[tracing::function("Storage.Blob.BlobClient.renewLease")]
1153    pub async fn renew_lease(
1154        &self,
1155        lease_id: String,
1156        options: Option<BlobClientRenewLeaseOptions<'_>>,
1157    ) -> Result<Response<BlobClientRenewLeaseResult, NoFormat>> {
1158        let options = options.unwrap_or_default();
1159        let ctx = options.method_options.context.to_borrowed();
1160        let mut url = self.endpoint.clone();
1161        let mut query_builder = url.query_builder();
1162        query_builder.append_pair("comp", "lease");
1163        if let Some(timeout) = options.timeout {
1164            query_builder.set_pair("timeout", timeout.to_string());
1165        }
1166        query_builder.build();
1167        let mut request = Request::new(url, Method::Put);
1168        if let Some(if_match) = options.if_match.as_ref() {
1169            request.insert_header("if-match", if_match.to_string());
1170        }
1171        if let Some(if_modified_since) = options.if_modified_since {
1172            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1173        }
1174        if let Some(if_none_match) = options.if_none_match.as_ref() {
1175            request.insert_header("if-none-match", if_none_match.to_string());
1176        }
1177        if let Some(if_unmodified_since) = options.if_unmodified_since {
1178            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1179        }
1180        if let Some(if_tags) = options.if_tags.as_ref() {
1181            request.insert_header("x-ms-if-tags", if_tags);
1182        }
1183        request.insert_header("x-ms-lease-action", "renew");
1184        request.insert_header("x-ms-lease-id", lease_id);
1185        request.insert_header("x-ms-version", &self.version);
1186        let rsp = self
1187            .pipeline
1188            .send(
1189                &ctx,
1190                &mut request,
1191                Some(PipelineSendOptions {
1192                    check_success: CheckSuccessOptions {
1193                        success_codes: &[200],
1194                    },
1195                    ..Default::default()
1196                }),
1197            )
1198            .await?;
1199        Ok(rsp.into())
1200    }
1201
1202    /// Set the immutability policy on the specified blob.
1203    ///
1204    /// # Arguments
1205    ///
1206    /// * `expiry` - The date-time that indicates the time at which the blob immutability policy will expire.
1207    /// * `options` - Optional parameters for the request.
1208    #[tracing::function("Storage.Blob.BlobClient.setImmutabilityPolicy")]
1209    pub async fn set_immutability_policy(
1210        &self,
1211        expiry: &OffsetDateTime,
1212        options: Option<BlobClientSetImmutabilityPolicyOptions<'_>>,
1213    ) -> Result<Response<(), NoFormat>> {
1214        let options = options.unwrap_or_default();
1215        let ctx = options.method_options.context.to_borrowed();
1216        let mut url = self.endpoint.clone();
1217        let mut query_builder = url.query_builder();
1218        query_builder.append_pair("comp", "immutabilityPolicies");
1219        if let Some(snapshot) = options.snapshot.as_ref() {
1220            query_builder.set_pair("snapshot", snapshot);
1221        }
1222        if let Some(timeout) = options.timeout {
1223            query_builder.set_pair("timeout", timeout.to_string());
1224        }
1225        if let Some(version_id) = options.version_id.as_ref() {
1226            query_builder.set_pair("versionid", version_id);
1227        }
1228        query_builder.build();
1229        let mut request = Request::new(url, Method::Put);
1230        if let Some(if_unmodified_since) = options.if_unmodified_since {
1231            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1232        }
1233        if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
1234            request.insert_header(
1235                "x-ms-immutability-policy-mode",
1236                immutability_policy_mode.to_string(),
1237            );
1238        }
1239        request.insert_header("x-ms-immutability-policy-until-date", to_rfc7231(expiry));
1240        request.insert_header("x-ms-version", &self.version);
1241        let rsp = self
1242            .pipeline
1243            .send(
1244                &ctx,
1245                &mut request,
1246                Some(PipelineSendOptions {
1247                    check_success: CheckSuccessOptions {
1248                        success_codes: &[200],
1249                    },
1250                    ..Default::default()
1251                }),
1252            )
1253            .await?;
1254        Ok(rsp.into())
1255    }
1256
1257    /// Sets a legal hold on the specified blob.
1258    ///
1259    /// # Arguments
1260    ///
1261    /// * `legal_hold` - Indicates whether the blob has a legal hold.
1262    /// * `options` - Optional parameters for the request.
1263    #[tracing::function("Storage.Blob.BlobClient.setLegalHold")]
1264    pub async fn set_legal_hold(
1265        &self,
1266        legal_hold: bool,
1267        options: Option<BlobClientSetLegalHoldOptions<'_>>,
1268    ) -> Result<Response<(), NoFormat>> {
1269        let options = options.unwrap_or_default();
1270        let ctx = options.method_options.context.to_borrowed();
1271        let mut url = self.endpoint.clone();
1272        let mut query_builder = url.query_builder();
1273        query_builder.append_pair("comp", "legalhold");
1274        if let Some(snapshot) = options.snapshot.as_ref() {
1275            query_builder.set_pair("snapshot", snapshot);
1276        }
1277        if let Some(timeout) = options.timeout {
1278            query_builder.set_pair("timeout", timeout.to_string());
1279        }
1280        if let Some(version_id) = options.version_id.as_ref() {
1281            query_builder.set_pair("versionid", version_id);
1282        }
1283        query_builder.build();
1284        let mut request = Request::new(url, Method::Put);
1285        request.insert_header("x-ms-legal-hold", legal_hold.to_string());
1286        request.insert_header("x-ms-version", &self.version);
1287        let rsp = self
1288            .pipeline
1289            .send(
1290                &ctx,
1291                &mut request,
1292                Some(PipelineSendOptions {
1293                    check_success: CheckSuccessOptions {
1294                        success_codes: &[200],
1295                    },
1296                    ..Default::default()
1297                }),
1298            )
1299            .await?;
1300        Ok(rsp.into())
1301    }
1302
1303    /// Sets user-defined metadata for the specified blob.
1304    ///
1305    /// # Arguments
1306    ///
1307    /// * `metadata` - The metadata headers.
1308    /// * `options` - Optional parameters for the request.
1309    #[tracing::function("Storage.Blob.BlobClient.setMetadata")]
1310    pub async fn set_metadata(
1311        &self,
1312        metadata: &HashMap<String, String>,
1313        options: Option<BlobClientSetMetadataOptions<'_>>,
1314    ) -> Result<Response<(), NoFormat>> {
1315        let options = options.unwrap_or_default();
1316        let ctx = options.method_options.context.to_borrowed();
1317        let mut url = self.endpoint.clone();
1318        let mut query_builder = url.query_builder();
1319        query_builder.append_pair("comp", "metadata");
1320        if let Some(timeout) = options.timeout {
1321            query_builder.set_pair("timeout", timeout.to_string());
1322        }
1323        query_builder.build();
1324        let mut request = Request::new(url, Method::Put);
1325        if let Some(if_match) = options.if_match.as_ref() {
1326            request.insert_header("if-match", if_match.to_string());
1327        }
1328        if let Some(if_modified_since) = options.if_modified_since {
1329            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1330        }
1331        if let Some(if_none_match) = options.if_none_match.as_ref() {
1332            request.insert_header("if-none-match", if_none_match.to_string());
1333        }
1334        if let Some(if_unmodified_since) = options.if_unmodified_since {
1335            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1336        }
1337        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
1338            request.insert_header(
1339                "x-ms-encryption-algorithm",
1340                encryption_algorithm.to_string(),
1341            );
1342        }
1343        if let Some(encryption_key) = options.encryption_key.as_ref() {
1344            request.insert_header("x-ms-encryption-key", encryption_key);
1345        }
1346        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
1347            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
1348        }
1349        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
1350            request.insert_header("x-ms-encryption-scope", encryption_scope);
1351        }
1352        if let Some(if_tags) = options.if_tags.as_ref() {
1353            request.insert_header("x-ms-if-tags", if_tags);
1354        }
1355        if let Some(lease_id) = options.lease_id.as_ref() {
1356            request.insert_header("x-ms-lease-id", lease_id);
1357        }
1358        for (k, v) in metadata {
1359            request.insert_header(format!("x-ms-meta-{k}"), v);
1360        }
1361        request.insert_header("x-ms-version", &self.version);
1362        let rsp = self
1363            .pipeline
1364            .send(
1365                &ctx,
1366                &mut request,
1367                Some(PipelineSendOptions {
1368                    check_success: CheckSuccessOptions {
1369                        success_codes: &[200],
1370                    },
1371                    ..Default::default()
1372                }),
1373            )
1374            .await?;
1375        Ok(rsp.into())
1376    }
1377
1378    /// Sets system properties on the specified blob.
1379    ///
1380    /// # Arguments
1381    ///
1382    /// * `options` - Optional parameters for the request.
1383    #[tracing::function("Storage.Blob.BlobClient.setProperties")]
1384    pub async fn set_properties(
1385        &self,
1386        options: Option<BlobClientSetPropertiesOptions<'_>>,
1387    ) -> Result<Response<(), NoFormat>> {
1388        let options = options.unwrap_or_default();
1389        let ctx = options.method_options.context.to_borrowed();
1390        let mut url = self.endpoint.clone();
1391        let mut query_builder = url.query_builder();
1392        query_builder.append_pair("comp", "properties");
1393        if let Some(timeout) = options.timeout {
1394            query_builder.set_pair("timeout", timeout.to_string());
1395        }
1396        query_builder.build();
1397        let mut request = Request::new(url, Method::Put);
1398        if let Some(if_match) = options.if_match.as_ref() {
1399            request.insert_header("if-match", if_match.to_string());
1400        }
1401        if let Some(if_modified_since) = options.if_modified_since {
1402            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1403        }
1404        if let Some(if_none_match) = options.if_none_match.as_ref() {
1405            request.insert_header("if-none-match", if_none_match.to_string());
1406        }
1407        if let Some(if_unmodified_since) = options.if_unmodified_since {
1408            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1409        }
1410        if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
1411            request.insert_header("x-ms-blob-cache-control", blob_cache_control);
1412        }
1413        if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
1414            request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
1415        }
1416        if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
1417            request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
1418        }
1419        if let Some(blob_content_language) = options.blob_content_language.as_ref() {
1420            request.insert_header("x-ms-blob-content-language", blob_content_language);
1421        }
1422        if let Some(blob_content_md5) = options.blob_content_md5 {
1423            request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
1424        }
1425        if let Some(blob_content_type) = options.blob_content_type.as_ref() {
1426            request.insert_header("x-ms-blob-content-type", blob_content_type);
1427        }
1428        if let Some(if_tags) = options.if_tags.as_ref() {
1429            request.insert_header("x-ms-if-tags", if_tags);
1430        }
1431        if let Some(lease_id) = options.lease_id.as_ref() {
1432            request.insert_header("x-ms-lease-id", lease_id);
1433        }
1434        request.insert_header("x-ms-version", &self.version);
1435        let rsp = self
1436            .pipeline
1437            .send(
1438                &ctx,
1439                &mut request,
1440                Some(PipelineSendOptions {
1441                    check_success: CheckSuccessOptions {
1442                        success_codes: &[200],
1443                    },
1444                    ..Default::default()
1445                }),
1446            )
1447            .await?;
1448        Ok(rsp.into())
1449    }
1450
1451    /// Sets the tags of the specified blob.
1452    ///
1453    /// # Arguments
1454    ///
1455    /// * `tags` - The blob tags.
1456    /// * `options` - Optional parameters for the request.
1457    #[tracing::function("Storage.Blob.BlobClient.setTags")]
1458    pub async fn set_tags(
1459        &self,
1460        tags: RequestContent<BlobTags, XmlFormat>,
1461        options: Option<BlobClientSetTagsOptions<'_>>,
1462    ) -> Result<Response<(), NoFormat>> {
1463        let options = options.unwrap_or_default();
1464        let ctx = options.method_options.context.to_borrowed();
1465        let mut url = self.endpoint.clone();
1466        let mut query_builder = url.query_builder();
1467        query_builder.append_pair("comp", "tags");
1468        if let Some(timeout) = options.timeout {
1469            query_builder.set_pair("timeout", timeout.to_string());
1470        }
1471        if let Some(version_id) = options.version_id.as_ref() {
1472            query_builder.set_pair("versionid", version_id);
1473        }
1474        query_builder.build();
1475        let mut request = Request::new(url, Method::Put);
1476        if let Some(transactional_content_md5) = options.transactional_content_md5 {
1477            request.insert_header("content-md5", base64::encode(transactional_content_md5));
1478        }
1479        request.insert_header("content-type", "application/xml");
1480        if let Some(if_match) = options.if_match.as_ref() {
1481            request.insert_header("x-ms-blob-if-match", if_match.to_string());
1482        }
1483        if let Some(if_modified_since) = options.if_modified_since {
1484            request.insert_header(
1485                "x-ms-blob-if-modified-since",
1486                to_rfc7231(&if_modified_since),
1487            );
1488        }
1489        if let Some(if_none_match) = options.if_none_match.as_ref() {
1490            request.insert_header("x-ms-blob-if-none-match", if_none_match.to_string());
1491        }
1492        if let Some(if_unmodified_since) = options.if_unmodified_since {
1493            request.insert_header(
1494                "x-ms-blob-if-unmodified-since",
1495                to_rfc7231(&if_unmodified_since),
1496            );
1497        }
1498        if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
1499            request.insert_header(
1500                "x-ms-content-crc64",
1501                base64::encode(transactional_content_crc64),
1502            );
1503        }
1504        if let Some(if_tags) = options.if_tags.as_ref() {
1505            request.insert_header("x-ms-if-tags", if_tags);
1506        }
1507        if let Some(lease_id) = options.lease_id.as_ref() {
1508            request.insert_header("x-ms-lease-id", lease_id);
1509        }
1510        request.insert_header("x-ms-version", &self.version);
1511        request.set_body(tags);
1512        let rsp = self
1513            .pipeline
1514            .send(
1515                &ctx,
1516                &mut request,
1517                Some(PipelineSendOptions {
1518                    check_success: CheckSuccessOptions {
1519                        success_codes: &[204],
1520                    },
1521                    ..Default::default()
1522                }),
1523            )
1524            .await?;
1525        Ok(rsp.into())
1526    }
1527
1528    /// Sets the tier of the specified blob.
1529    ///
1530    /// # Arguments
1531    ///
1532    /// * `tier` - Indicates the tier to be set on the blob.
1533    /// * `options` - Optional parameters for the request.
1534    #[tracing::function("Storage.Blob.BlobClient.setTier")]
1535    pub async fn set_tier(
1536        &self,
1537        tier: AccessTier,
1538        options: Option<BlobClientSetTierOptions<'_>>,
1539    ) -> Result<Response<(), NoFormat>> {
1540        let options = options.unwrap_or_default();
1541        let ctx = options.method_options.context.to_borrowed();
1542        let mut url = self.endpoint.clone();
1543        let mut query_builder = url.query_builder();
1544        query_builder.append_pair("comp", "tier");
1545        if let Some(snapshot) = options.snapshot.as_ref() {
1546            query_builder.set_pair("snapshot", snapshot);
1547        }
1548        if let Some(timeout) = options.timeout {
1549            query_builder.set_pair("timeout", timeout.to_string());
1550        }
1551        if let Some(version_id) = options.version_id.as_ref() {
1552            query_builder.set_pair("versionid", version_id);
1553        }
1554        query_builder.build();
1555        let mut request = Request::new(url, Method::Put);
1556        request.insert_header("x-ms-access-tier", tier.to_string());
1557        if let Some(if_tags) = options.if_tags.as_ref() {
1558            request.insert_header("x-ms-if-tags", if_tags);
1559        }
1560        if let Some(lease_id) = options.lease_id.as_ref() {
1561            request.insert_header("x-ms-lease-id", lease_id);
1562        }
1563        if let Some(rehydrate_priority) = options.rehydrate_priority.as_ref() {
1564            request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string());
1565        }
1566        request.insert_header("x-ms-version", &self.version);
1567        let rsp = self
1568            .pipeline
1569            .send(
1570                &ctx,
1571                &mut request,
1572                Some(PipelineSendOptions {
1573                    check_success: CheckSuccessOptions {
1574                        success_codes: &[200, 202],
1575                    },
1576                    ..Default::default()
1577                }),
1578            )
1579            .await?;
1580        Ok(rsp.into())
1581    }
1582
1583    /// Starts an asynchronous copy from a source URL to a destination blob.
1584    ///
1585    /// # Arguments
1586    ///
1587    /// * `copy_source` - Specifies the name of the source URL for the copy operation. The value should be URL-encoded as it would
1588    ///   appear in a request URI.
1589    /// * `options` - Optional parameters for the request.
1590    ///
1591    /// ## Response Headers
1592    ///
1593    /// The returned [`Response`](azure_core::http::Response) implements the [`BlobClientStartCopyFromUrlResultHeaders`] trait, which provides
1594    /// access to response headers. For example:
1595    ///
1596    /// ```no_run
1597    /// use azure_core::{Result, http::{Response, NoFormat}};
1598    /// use azure_storage_blob::models::{BlobClientStartCopyFromUrlResult, BlobClientStartCopyFromUrlResultHeaders};
1599    /// async fn example() -> Result<()> {
1600    ///     let response: Response<BlobClientStartCopyFromUrlResult, NoFormat> = unimplemented!();
1601    ///     // Access response headers
1602    ///     if let Some(etag) = response.etag()? {
1603    ///         println!("etag: {:?}", etag);
1604    ///     }
1605    ///     if let Some(last_modified) = response.last_modified()? {
1606    ///         println!("last-modified: {:?}", last_modified);
1607    ///     }
1608    ///     if let Some(copy_id) = response.copy_id()? {
1609    ///         println!("x-ms-copy-id: {:?}", copy_id);
1610    ///     }
1611    ///     Ok(())
1612    /// }
1613    /// ```
1614    ///
1615    /// ### Available headers
1616    /// * [`etag`()](crate::generated::models::BlobClientStartCopyFromUrlResultHeaders::etag) - etag
1617    /// * [`last_modified`()](crate::generated::models::BlobClientStartCopyFromUrlResultHeaders::last_modified) - last-modified
1618    /// * [`copy_id`()](crate::generated::models::BlobClientStartCopyFromUrlResultHeaders::copy_id) - x-ms-copy-id
1619    /// * [`copy_status`()](crate::generated::models::BlobClientStartCopyFromUrlResultHeaders::copy_status) - x-ms-copy-status
1620    /// * [`version_id`()](crate::generated::models::BlobClientStartCopyFromUrlResultHeaders::version_id) - x-ms-version-id
1621    ///
1622    /// [`BlobClientStartCopyFromUrlResultHeaders`]: crate::generated::models::BlobClientStartCopyFromUrlResultHeaders
1623    #[tracing::function("Storage.Blob.BlobClient.startCopyFromUrl")]
1624    pub async fn start_copy_from_url(
1625        &self,
1626        copy_source: String,
1627        options: Option<BlobClientStartCopyFromUrlOptions<'_>>,
1628    ) -> Result<Response<BlobClientStartCopyFromUrlResult, NoFormat>> {
1629        let options = options.unwrap_or_default();
1630        let ctx = options.method_options.context.to_borrowed();
1631        let mut url = self.endpoint.clone();
1632        let mut query_builder = url.query_builder();
1633        if let Some(timeout) = options.timeout {
1634            query_builder.set_pair("timeout", timeout.to_string());
1635        }
1636        query_builder.build();
1637        let mut request = Request::new(url, Method::Put);
1638        if let Some(if_match) = options.if_match.as_ref() {
1639            request.insert_header("if-match", if_match.to_string());
1640        }
1641        if let Some(if_modified_since) = options.if_modified_since {
1642            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
1643        }
1644        if let Some(if_none_match) = options.if_none_match.as_ref() {
1645            request.insert_header("if-none-match", if_none_match.to_string());
1646        }
1647        if let Some(if_unmodified_since) = options.if_unmodified_since {
1648            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
1649        }
1650        if let Some(tier) = options.tier.as_ref() {
1651            request.insert_header("x-ms-access-tier", tier.to_string());
1652        }
1653        request.insert_header("x-ms-copy-source", copy_source);
1654        if let Some(if_tags) = options.if_tags.as_ref() {
1655            request.insert_header("x-ms-if-tags", if_tags);
1656        }
1657        if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
1658            request.insert_header(
1659                "x-ms-immutability-policy-mode",
1660                immutability_policy_mode.to_string(),
1661            );
1662        }
1663        if let Some(immutability_policy_expiry) = options.immutability_policy_expiry {
1664            request.insert_header(
1665                "x-ms-immutability-policy-until-date",
1666                to_rfc7231(&immutability_policy_expiry),
1667            );
1668        }
1669        if let Some(lease_id) = options.lease_id.as_ref() {
1670            request.insert_header("x-ms-lease-id", lease_id);
1671        }
1672        if let Some(legal_hold) = options.legal_hold {
1673            request.insert_header("x-ms-legal-hold", legal_hold.to_string());
1674        }
1675        if let Some(metadata) = options.metadata.as_ref() {
1676            for (k, v) in metadata {
1677                request.insert_header(format!("x-ms-meta-{k}"), v);
1678            }
1679        }
1680        if let Some(rehydrate_priority) = options.rehydrate_priority.as_ref() {
1681            request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string());
1682        }
1683        if let Some(seal_blob) = options.seal_blob {
1684            request.insert_header("x-ms-seal-blob", seal_blob.to_string());
1685        }
1686        if let Some(source_if_match) = options.source_if_match.as_ref() {
1687            request.insert_header("x-ms-source-if-match", source_if_match.to_string());
1688        }
1689        if let Some(source_if_modified_since) = options.source_if_modified_since {
1690            request.insert_header(
1691                "x-ms-source-if-modified-since",
1692                to_rfc7231(&source_if_modified_since),
1693            );
1694        }
1695        if let Some(source_if_none_match) = options.source_if_none_match.as_ref() {
1696            request.insert_header(
1697                "x-ms-source-if-none-match",
1698                source_if_none_match.to_string(),
1699            );
1700        }
1701        if let Some(source_if_tags) = options.source_if_tags.as_ref() {
1702            request.insert_header("x-ms-source-if-tags", source_if_tags);
1703        }
1704        if let Some(source_if_unmodified_since) = options.source_if_unmodified_since {
1705            request.insert_header(
1706                "x-ms-source-if-unmodified-since",
1707                to_rfc7231(&source_if_unmodified_since),
1708            );
1709        }
1710        if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
1711            request.insert_header("x-ms-tags", blob_tags_string);
1712        }
1713        request.insert_header("x-ms-version", &self.version);
1714        let rsp = self
1715            .pipeline
1716            .send(
1717                &ctx,
1718                &mut request,
1719                Some(PipelineSendOptions {
1720                    check_success: CheckSuccessOptions {
1721                        success_codes: &[202],
1722                    },
1723                    ..Default::default()
1724                }),
1725            )
1726            .await?;
1727        Ok(rsp.into())
1728    }
1729
1730    /// Undelete the specified previously soft deleted blob.
1731    ///
1732    /// # Arguments
1733    ///
1734    /// * `options` - Optional parameters for the request.
1735    #[tracing::function("Storage.Blob.BlobClient.undelete")]
1736    pub async fn undelete(
1737        &self,
1738        options: Option<BlobClientUndeleteOptions<'_>>,
1739    ) -> Result<Response<(), NoFormat>> {
1740        let options = options.unwrap_or_default();
1741        let ctx = options.method_options.context.to_borrowed();
1742        let mut url = self.endpoint.clone();
1743        let mut query_builder = url.query_builder();
1744        query_builder.append_pair("comp", "undelete");
1745        if let Some(timeout) = options.timeout {
1746            query_builder.set_pair("timeout", timeout.to_string());
1747        }
1748        query_builder.build();
1749        let mut request = Request::new(url, Method::Put);
1750        request.insert_header("x-ms-version", &self.version);
1751        let rsp = self
1752            .pipeline
1753            .send(
1754                &ctx,
1755                &mut request,
1756                Some(PipelineSendOptions {
1757                    check_success: CheckSuccessOptions {
1758                        success_codes: &[200],
1759                    },
1760                    ..Default::default()
1761                }),
1762            )
1763            .await?;
1764        Ok(rsp.into())
1765    }
1766}
1767
1768/// Default value for [`BlobClientOptions::version`].
1769pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
1770
1771impl Default for BlobClientOptions {
1772    fn default() -> Self {
1773        Self {
1774            client_options: ClientOptions::default(),
1775            version: String::from(DEFAULT_VERSION),
1776        }
1777    }
1778}