Skip to main content

azure_storage_blob/generated/clients/
block_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    BlockBlobClientCommitBlockListOptions, BlockBlobClientCommitBlockListResult,
8    BlockBlobClientGetBlockListOptions, BlockBlobClientStageBlockFromUrlOptions,
9    BlockBlobClientStageBlockFromUrlResult, BlockBlobClientStageBlockOptions,
10    BlockBlobClientStageBlockResult, BlockBlobClientUploadBlobFromUrlOptions,
11    BlockBlobClientUploadBlobFromUrlResult, BlockBlobClientUploadInternalOptions,
12    BlockBlobClientUploadInternalResult, BlockList, BlockListType, BlockLookupList,
13};
14use azure_core::{
15    base64,
16    error::CheckSuccessOptions,
17    fmt::SafeDebug,
18    http::{
19        ClientOptions, Method, NoFormat, Pipeline, PipelineSendOptions, Request, RequestContent,
20        Response, Url, UrlExt, XmlFormat,
21    },
22    time::to_rfc7231,
23    tracing, Bytes, Result,
24};
25
26#[tracing::client]
27pub struct BlockBlobClient {
28    pub(crate) endpoint: Url,
29    pub(crate) pipeline: Pipeline,
30    pub(crate) version: String,
31}
32
33/// Options used when creating a `BlockBlobClient`
34#[derive(Clone, SafeDebug)]
35pub struct BlockBlobClientOptions {
36    /// Allows customization of the client.
37    pub client_options: ClientOptions,
38    /// Specifies the version of the operation to use for this request.
39    pub version: String,
40}
41
42impl BlockBlobClient {
43    /// Writes to the block blob by specifying the list of block IDs that make up the blob.
44    ///
45    /// # Arguments
46    ///
47    /// * `blocks` - Blob blocks.
48    /// * `options` - Optional parameters for the request.
49    ///
50    /// ## Response Headers
51    ///
52    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockBlobClientCommitBlockListResultHeaders`] trait, which provides
53    /// access to response headers. For example:
54    ///
55    /// ```no_run
56    /// use azure_core::{Result, http::{Response, NoFormat}};
57    /// use azure_storage_blob::models::{BlockBlobClientCommitBlockListResult, BlockBlobClientCommitBlockListResultHeaders};
58    /// async fn example() -> Result<()> {
59    ///     let response: Response<BlockBlobClientCommitBlockListResult, NoFormat> = unimplemented!();
60    ///     // Access response headers
61    ///     if let Some(content_md5) = response.content_md5()? {
62    ///         println!("content-md5: {:?}", content_md5);
63    ///     }
64    ///     if let Some(etag) = response.etag()? {
65    ///         println!("etag: {:?}", etag);
66    ///     }
67    ///     if let Some(last_modified) = response.last_modified()? {
68    ///         println!("last-modified: {:?}", last_modified);
69    ///     }
70    ///     Ok(())
71    /// }
72    /// ```
73    ///
74    /// ### Available headers
75    /// * [`content_md5`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::content_md5) - content-md5
76    /// * [`etag`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::etag) - etag
77    /// * [`last_modified`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::last_modified) - last-modified
78    /// * [`content_crc64`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::content_crc64) - x-ms-content-crc64
79    /// * [`encryption_key_sha256`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
80    /// * [`encryption_scope`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::encryption_scope) - x-ms-encryption-scope
81    /// * [`is_server_encrypted`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
82    /// * [`version_id`()](crate::generated::models::BlockBlobClientCommitBlockListResultHeaders::version_id) - x-ms-version-id
83    ///
84    /// [`BlockBlobClientCommitBlockListResultHeaders`]: crate::generated::models::BlockBlobClientCommitBlockListResultHeaders
85    #[tracing::function("Storage.Blob.BlockBlobClient.commitBlockList")]
86    pub async fn commit_block_list(
87        &self,
88        blocks: RequestContent<BlockLookupList, XmlFormat>,
89        options: Option<BlockBlobClientCommitBlockListOptions<'_>>,
90    ) -> Result<Response<BlockBlobClientCommitBlockListResult, NoFormat>> {
91        let options = options.unwrap_or_default();
92        let ctx = options.method_options.context.to_borrowed();
93        let mut url = self.endpoint.clone();
94        let mut query_builder = url.query_builder();
95        query_builder.append_pair("comp", "blocklist");
96        if let Some(timeout) = options.timeout {
97            query_builder.set_pair("timeout", timeout.to_string());
98        }
99        query_builder.build();
100        let mut request = Request::new(url, Method::Put);
101        if let Some(transactional_content_md5) = options.transactional_content_md5 {
102            request.insert_header("content-md5", base64::encode(transactional_content_md5));
103        }
104        request.insert_header("content-type", "application/xml");
105        if let Some(if_match) = options.if_match.as_ref() {
106            request.insert_header("if-match", if_match.to_string());
107        }
108        if let Some(if_modified_since) = options.if_modified_since {
109            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
110        }
111        if let Some(if_none_match) = options.if_none_match.as_ref() {
112            request.insert_header("if-none-match", if_none_match.to_string());
113        }
114        if let Some(if_unmodified_since) = options.if_unmodified_since {
115            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
116        }
117        if let Some(tier) = options.tier.as_ref() {
118            request.insert_header("x-ms-access-tier", tier.to_string());
119        }
120        if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
121            request.insert_header("x-ms-blob-cache-control", blob_cache_control);
122        }
123        if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
124            request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
125        }
126        if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
127            request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
128        }
129        if let Some(blob_content_language) = options.blob_content_language.as_ref() {
130            request.insert_header("x-ms-blob-content-language", blob_content_language);
131        }
132        if let Some(blob_content_md5) = options.blob_content_md5 {
133            request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
134        }
135        if let Some(blob_content_type) = options.blob_content_type.as_ref() {
136            request.insert_header("x-ms-blob-content-type", blob_content_type);
137        }
138        if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
139            request.insert_header(
140                "x-ms-content-crc64",
141                base64::encode(transactional_content_crc64),
142            );
143        }
144        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
145            request.insert_header(
146                "x-ms-encryption-algorithm",
147                encryption_algorithm.to_string(),
148            );
149        }
150        if let Some(encryption_key) = options.encryption_key.as_ref() {
151            request.insert_header("x-ms-encryption-key", encryption_key);
152        }
153        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
154            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
155        }
156        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
157            request.insert_header("x-ms-encryption-scope", encryption_scope);
158        }
159        if let Some(if_tags) = options.if_tags.as_ref() {
160            request.insert_header("x-ms-if-tags", if_tags);
161        }
162        if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
163            request.insert_header(
164                "x-ms-immutability-policy-mode",
165                immutability_policy_mode.to_string(),
166            );
167        }
168        if let Some(immutability_policy_expiry) = options.immutability_policy_expiry {
169            request.insert_header(
170                "x-ms-immutability-policy-until-date",
171                to_rfc7231(&immutability_policy_expiry),
172            );
173        }
174        if let Some(lease_id) = options.lease_id.as_ref() {
175            request.insert_header("x-ms-lease-id", lease_id);
176        }
177        if let Some(legal_hold) = options.legal_hold {
178            request.insert_header("x-ms-legal-hold", legal_hold.to_string());
179        }
180        if let Some(metadata) = options.metadata.as_ref() {
181            for (k, v) in metadata {
182                request.insert_header(format!("x-ms-meta-{k}"), v);
183            }
184        }
185        if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
186            request.insert_header("x-ms-tags", blob_tags_string);
187        }
188        request.insert_header("x-ms-version", &self.version);
189        request.set_body(blocks);
190        let rsp = self
191            .pipeline
192            .send(
193                &ctx,
194                &mut request,
195                Some(PipelineSendOptions {
196                    check_success: CheckSuccessOptions {
197                        success_codes: &[201],
198                    },
199                    ..Default::default()
200                }),
201            )
202            .await?;
203        Ok(rsp.into())
204    }
205
206    /// Retrieves the list of blocks that have been uploaded as part of the block blob.
207    ///
208    /// # Arguments
209    ///
210    /// * `list_type` - Specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists
211    ///   together.
212    /// * `options` - Optional parameters for the request.
213    ///
214    /// ## Response Headers
215    ///
216    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockListHeaders`] trait, which provides
217    /// access to response headers. For example:
218    ///
219    /// ```no_run
220    /// use azure_core::{Result, http::{Response, XmlFormat}};
221    /// use azure_storage_blob::models::{BlockList, BlockListHeaders};
222    /// async fn example() -> Result<()> {
223    ///     let response: Response<BlockList, XmlFormat> = unimplemented!();
224    ///     // Access response headers
225    ///     if let Some(etag) = response.etag()? {
226    ///         println!("etag: {:?}", etag);
227    ///     }
228    ///     if let Some(last_modified) = response.last_modified()? {
229    ///         println!("last-modified: {:?}", last_modified);
230    ///     }
231    ///     if let Some(blob_content_length) = response.blob_content_length()? {
232    ///         println!("x-ms-blob-content-length: {:?}", blob_content_length);
233    ///     }
234    ///     Ok(())
235    /// }
236    /// ```
237    ///
238    /// ### Available headers
239    /// * [`etag`()](crate::generated::models::BlockListHeaders::etag) - etag
240    /// * [`last_modified`()](crate::generated::models::BlockListHeaders::last_modified) - last-modified
241    /// * [`blob_content_length`()](crate::generated::models::BlockListHeaders::blob_content_length) - x-ms-blob-content-length
242    ///
243    /// [`BlockListHeaders`]: crate::generated::models::BlockListHeaders
244    #[tracing::function("Storage.Blob.BlockBlobClient.getBlockList")]
245    pub async fn get_block_list(
246        &self,
247        list_type: BlockListType,
248        options: Option<BlockBlobClientGetBlockListOptions<'_>>,
249    ) -> Result<Response<BlockList, XmlFormat>> {
250        let options = options.unwrap_or_default();
251        let ctx = options.method_options.context.to_borrowed();
252        let mut url = self.endpoint.clone();
253        let mut query_builder = url.query_builder();
254        query_builder.append_pair("comp", "blocklist");
255        query_builder.set_pair("blocklisttype", list_type.as_ref());
256        if let Some(snapshot) = options.snapshot.as_ref() {
257            query_builder.set_pair("snapshot", snapshot);
258        }
259        if let Some(timeout) = options.timeout {
260            query_builder.set_pair("timeout", timeout.to_string());
261        }
262        query_builder.build();
263        let mut request = Request::new(url, Method::Get);
264        request.insert_header("accept", "application/xml");
265        if let Some(if_tags) = options.if_tags.as_ref() {
266            request.insert_header("x-ms-if-tags", if_tags);
267        }
268        if let Some(lease_id) = options.lease_id.as_ref() {
269            request.insert_header("x-ms-lease-id", lease_id);
270        }
271        request.insert_header("x-ms-version", &self.version);
272        let rsp = self
273            .pipeline
274            .send(
275                &ctx,
276                &mut request,
277                Some(PipelineSendOptions {
278                    check_success: CheckSuccessOptions {
279                        success_codes: &[200],
280                    },
281                    ..Default::default()
282                }),
283            )
284            .await?;
285        Ok(rsp.into())
286    }
287
288    /// Creates a new block of data to be committed as part of a blob.
289    ///
290    /// # Arguments
291    ///
292    /// * `block_id` - A Base64 value that identifies the block. Prior to encoding, the string must be less than or equal to 64
293    ///   bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for
294    ///   each block.
295    /// * `content_length` - The length of the request.
296    /// * `body` - The body of the request.
297    /// * `options` - Optional parameters for the request.
298    ///
299    /// ## Response Headers
300    ///
301    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockBlobClientStageBlockResultHeaders`] trait, which provides
302    /// access to response headers. For example:
303    ///
304    /// ```no_run
305    /// use azure_core::{Result, http::{Response, NoFormat}};
306    /// use azure_storage_blob::models::{BlockBlobClientStageBlockResult, BlockBlobClientStageBlockResultHeaders};
307    /// async fn example() -> Result<()> {
308    ///     let response: Response<BlockBlobClientStageBlockResult, NoFormat> = unimplemented!();
309    ///     // Access response headers
310    ///     if let Some(content_md5) = response.content_md5()? {
311    ///         println!("content-md5: {:?}", content_md5);
312    ///     }
313    ///     if let Some(content_crc64) = response.content_crc64()? {
314    ///         println!("x-ms-content-crc64: {:?}", content_crc64);
315    ///     }
316    ///     if let Some(encryption_key_sha256) = response.encryption_key_sha256()? {
317    ///         println!("x-ms-encryption-key-sha256: {:?}", encryption_key_sha256);
318    ///     }
319    ///     Ok(())
320    /// }
321    /// ```
322    ///
323    /// ### Available headers
324    /// * [`content_md5`()](crate::generated::models::BlockBlobClientStageBlockResultHeaders::content_md5) - content-md5
325    /// * [`content_crc64`()](crate::generated::models::BlockBlobClientStageBlockResultHeaders::content_crc64) - x-ms-content-crc64
326    /// * [`encryption_key_sha256`()](crate::generated::models::BlockBlobClientStageBlockResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
327    /// * [`encryption_scope`()](crate::generated::models::BlockBlobClientStageBlockResultHeaders::encryption_scope) - x-ms-encryption-scope
328    /// * [`is_server_encrypted`()](crate::generated::models::BlockBlobClientStageBlockResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
329    ///
330    /// [`BlockBlobClientStageBlockResultHeaders`]: crate::generated::models::BlockBlobClientStageBlockResultHeaders
331    #[tracing::function("Storage.Blob.BlockBlobClient.stageBlock")]
332    pub async fn stage_block(
333        &self,
334        block_id: &[u8],
335        content_length: u64,
336        body: RequestContent<Bytes, NoFormat>,
337        options: Option<BlockBlobClientStageBlockOptions<'_>>,
338    ) -> Result<Response<BlockBlobClientStageBlockResult, NoFormat>> {
339        let options = options.unwrap_or_default();
340        let ctx = options.method_options.context.to_borrowed();
341        let mut url = self.endpoint.clone();
342        let mut query_builder = url.query_builder();
343        query_builder.append_pair("comp", "block");
344        query_builder.set_pair("blockid", base64::encode(block_id));
345        if let Some(timeout) = options.timeout {
346            query_builder.set_pair("timeout", timeout.to_string());
347        }
348        query_builder.build();
349        let mut request = Request::new(url, Method::Put);
350        request.insert_header("content-length", content_length.to_string());
351        if let Some(transactional_content_md5) = options.transactional_content_md5 {
352            request.insert_header("content-md5", base64::encode(transactional_content_md5));
353        }
354        request.insert_header("content-type", "application/octet-stream");
355        if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
356            request.insert_header(
357                "x-ms-content-crc64",
358                base64::encode(transactional_content_crc64),
359            );
360        }
361        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
362            request.insert_header(
363                "x-ms-encryption-algorithm",
364                encryption_algorithm.to_string(),
365            );
366        }
367        if let Some(encryption_key) = options.encryption_key.as_ref() {
368            request.insert_header("x-ms-encryption-key", encryption_key);
369        }
370        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
371            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
372        }
373        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
374            request.insert_header("x-ms-encryption-scope", encryption_scope);
375        }
376        if let Some(lease_id) = options.lease_id.as_ref() {
377            request.insert_header("x-ms-lease-id", lease_id);
378        }
379        request.insert_header("x-ms-version", &self.version);
380        request.set_body(body);
381        let rsp = self
382            .pipeline
383            .send(
384                &ctx,
385                &mut request,
386                Some(PipelineSendOptions {
387                    check_success: CheckSuccessOptions {
388                        success_codes: &[201],
389                    },
390                    ..Default::default()
391                }),
392            )
393            .await?;
394        Ok(rsp.into())
395    }
396
397    /// Creates a new block of data from the specified URL to be committed as part of a blob.
398    ///
399    /// # Arguments
400    ///
401    /// * `block_id` - A Base64 value that identifies the block. Prior to encoding, the string must be less than or equal to 64
402    ///   bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the same size for
403    ///   each block.
404    /// * `content_length` - The length of the request.
405    /// * `source_url` - Specifies the URL of the source.
406    /// * `options` - Optional parameters for the request.
407    ///
408    /// ## Response Headers
409    ///
410    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockBlobClientStageBlockFromUrlResultHeaders`] trait, which provides
411    /// access to response headers. For example:
412    ///
413    /// ```no_run
414    /// use azure_core::{Result, http::{Response, NoFormat}};
415    /// use azure_storage_blob::models::{BlockBlobClientStageBlockFromUrlResult, BlockBlobClientStageBlockFromUrlResultHeaders};
416    /// async fn example() -> Result<()> {
417    ///     let response: Response<BlockBlobClientStageBlockFromUrlResult, NoFormat> = unimplemented!();
418    ///     // Access response headers
419    ///     if let Some(content_md5) = response.content_md5()? {
420    ///         println!("content-md5: {:?}", content_md5);
421    ///     }
422    ///     if let Some(content_crc64) = response.content_crc64()? {
423    ///         println!("x-ms-content-crc64: {:?}", content_crc64);
424    ///     }
425    ///     if let Some(encryption_key_sha256) = response.encryption_key_sha256()? {
426    ///         println!("x-ms-encryption-key-sha256: {:?}", encryption_key_sha256);
427    ///     }
428    ///     Ok(())
429    /// }
430    /// ```
431    ///
432    /// ### Available headers
433    /// * [`content_md5`()](crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders::content_md5) - content-md5
434    /// * [`content_crc64`()](crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders::content_crc64) - x-ms-content-crc64
435    /// * [`encryption_key_sha256`()](crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
436    /// * [`encryption_scope`()](crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders::encryption_scope) - x-ms-encryption-scope
437    /// * [`is_server_encrypted`()](crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
438    ///
439    /// [`BlockBlobClientStageBlockFromUrlResultHeaders`]: crate::generated::models::BlockBlobClientStageBlockFromUrlResultHeaders
440    #[tracing::function("Storage.Blob.BlockBlobClient.stageBlockFromUrl")]
441    pub async fn stage_block_from_url(
442        &self,
443        block_id: &[u8],
444        content_length: u64,
445        source_url: String,
446        options: Option<BlockBlobClientStageBlockFromUrlOptions<'_>>,
447    ) -> Result<Response<BlockBlobClientStageBlockFromUrlResult, NoFormat>> {
448        let options = options.unwrap_or_default();
449        let ctx = options.method_options.context.to_borrowed();
450        let mut url = self.endpoint.clone();
451        let mut query_builder = url.query_builder();
452        query_builder.append_pair("comp", "block");
453        query_builder.set_pair("blockid", base64::encode(block_id));
454        if let Some(timeout) = options.timeout {
455            query_builder.set_pair("timeout", timeout.to_string());
456        }
457        query_builder.build();
458        let mut request = Request::new(url, Method::Put);
459        request.insert_header("content-length", content_length.to_string());
460        request.insert_header("x-ms-copy-source", source_url);
461        if let Some(copy_source_authorization) = options.copy_source_authorization.as_ref() {
462            request.insert_header("x-ms-copy-source-authorization", copy_source_authorization);
463        }
464        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
465            request.insert_header(
466                "x-ms-encryption-algorithm",
467                encryption_algorithm.to_string(),
468            );
469        }
470        if let Some(encryption_key) = options.encryption_key.as_ref() {
471            request.insert_header("x-ms-encryption-key", encryption_key);
472        }
473        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
474            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
475        }
476        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
477            request.insert_header("x-ms-encryption-scope", encryption_scope);
478        }
479        if let Some(file_request_intent) = options.file_request_intent.as_ref() {
480            request.insert_header("x-ms-file-request-intent", file_request_intent.to_string());
481        }
482        if let Some(lease_id) = options.lease_id.as_ref() {
483            request.insert_header("x-ms-lease-id", lease_id);
484        }
485        if let Some(source_content_crc64) = options.source_content_crc64 {
486            request.insert_header(
487                "x-ms-source-content-crc64",
488                base64::encode(source_content_crc64),
489            );
490        }
491        if let Some(source_content_md5) = options.source_content_md5 {
492            request.insert_header(
493                "x-ms-source-content-md5",
494                base64::encode(source_content_md5),
495            );
496        }
497        if let Some(source_encryption_algorithm) = options.source_encryption_algorithm.as_ref() {
498            request.insert_header(
499                "x-ms-source-encryption-algorithm",
500                source_encryption_algorithm.to_string(),
501            );
502        }
503        if let Some(source_encryption_key) = options.source_encryption_key.as_ref() {
504            request.insert_header("x-ms-source-encryption-key", source_encryption_key);
505        }
506        if let Some(source_encryption_key_sha256) = options.source_encryption_key_sha256.as_ref() {
507            request.insert_header(
508                "x-ms-source-encryption-key-sha256",
509                source_encryption_key_sha256,
510            );
511        }
512        if let Some(source_if_match) = options.source_if_match.as_ref() {
513            request.insert_header("x-ms-source-if-match", source_if_match.to_string());
514        }
515        if let Some(source_if_modified_since) = options.source_if_modified_since {
516            request.insert_header(
517                "x-ms-source-if-modified-since",
518                to_rfc7231(&source_if_modified_since),
519            );
520        }
521        if let Some(source_if_none_match) = options.source_if_none_match.as_ref() {
522            request.insert_header(
523                "x-ms-source-if-none-match",
524                source_if_none_match.to_string(),
525            );
526        }
527        if let Some(source_if_unmodified_since) = options.source_if_unmodified_since {
528            request.insert_header(
529                "x-ms-source-if-unmodified-since",
530                to_rfc7231(&source_if_unmodified_since),
531            );
532        }
533        if let Some(source_range) = options.source_range.as_ref() {
534            request.insert_header("x-ms-source-range", source_range.to_string());
535        }
536        request.insert_header("x-ms-version", &self.version);
537        let rsp = self
538            .pipeline
539            .send(
540                &ctx,
541                &mut request,
542                Some(PipelineSendOptions {
543                    check_success: CheckSuccessOptions {
544                        success_codes: &[201],
545                    },
546                    ..Default::default()
547                }),
548            )
549            .await?;
550        Ok(rsp.into())
551    }
552
553    /// Uploads the content from the specified URL to the block blob. If the blob already exists, the data and any existing metadata
554    /// will be overwritten.
555    ///
556    /// # Arguments
557    ///
558    /// * `copy_source` - Specifies the name of the source URL for the copy operation. The value should be URL-encoded as it would
559    ///   appear in a request URI.
560    /// * `options` - Optional parameters for the request.
561    ///
562    /// ## Response Headers
563    ///
564    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockBlobClientUploadBlobFromUrlResultHeaders`] trait, which provides
565    /// access to response headers. For example:
566    ///
567    /// ```no_run
568    /// use azure_core::{Result, http::{Response, NoFormat}};
569    /// use azure_storage_blob::models::{BlockBlobClientUploadBlobFromUrlResult, BlockBlobClientUploadBlobFromUrlResultHeaders};
570    /// async fn example() -> Result<()> {
571    ///     let response: Response<BlockBlobClientUploadBlobFromUrlResult, NoFormat> = unimplemented!();
572    ///     // Access response headers
573    ///     if let Some(content_md5) = response.content_md5()? {
574    ///         println!("content-md5: {:?}", content_md5);
575    ///     }
576    ///     if let Some(etag) = response.etag()? {
577    ///         println!("etag: {:?}", etag);
578    ///     }
579    ///     if let Some(last_modified) = response.last_modified()? {
580    ///         println!("last-modified: {:?}", last_modified);
581    ///     }
582    ///     Ok(())
583    /// }
584    /// ```
585    ///
586    /// ### Available headers
587    /// * [`content_md5`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::content_md5) - content-md5
588    /// * [`etag`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::etag) - etag
589    /// * [`last_modified`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::last_modified) - last-modified
590    /// * [`encryption_key_sha256`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
591    /// * [`encryption_scope`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::encryption_scope) - x-ms-encryption-scope
592    /// * [`is_server_encrypted`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
593    /// * [`version_id`()](crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders::version_id) - x-ms-version-id
594    ///
595    /// [`BlockBlobClientUploadBlobFromUrlResultHeaders`]: crate::generated::models::BlockBlobClientUploadBlobFromUrlResultHeaders
596    #[tracing::function("Storage.Blob.BlockBlobClient.uploadBlobFromUrl")]
597    pub async fn upload_blob_from_url(
598        &self,
599        copy_source: String,
600        options: Option<BlockBlobClientUploadBlobFromUrlOptions<'_>>,
601    ) -> Result<Response<BlockBlobClientUploadBlobFromUrlResult, NoFormat>> {
602        let options = options.unwrap_or_default();
603        let ctx = options.method_options.context.to_borrowed();
604        let mut url = self.endpoint.clone();
605        let mut query_builder = url.query_builder();
606        if let Some(timeout) = options.timeout {
607            query_builder.set_pair("timeout", timeout.to_string());
608        }
609        query_builder.build();
610        let mut request = Request::new(url, Method::Put);
611        request.insert_header("content-length", "0");
612        if let Some(transactional_content_md5) = options.transactional_content_md5 {
613            request.insert_header("content-md5", base64::encode(transactional_content_md5));
614        }
615        if let Some(if_match) = options.if_match.as_ref() {
616            request.insert_header("if-match", if_match.to_string());
617        }
618        if let Some(if_modified_since) = options.if_modified_since {
619            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
620        }
621        if let Some(if_none_match) = options.if_none_match.as_ref() {
622            request.insert_header("if-none-match", if_none_match.to_string());
623        }
624        if let Some(if_unmodified_since) = options.if_unmodified_since {
625            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
626        }
627        if let Some(tier) = options.tier.as_ref() {
628            request.insert_header("x-ms-access-tier", tier.to_string());
629        }
630        if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
631            request.insert_header("x-ms-blob-cache-control", blob_cache_control);
632        }
633        if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
634            request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
635        }
636        if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
637            request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
638        }
639        if let Some(blob_content_language) = options.blob_content_language.as_ref() {
640            request.insert_header("x-ms-blob-content-language", blob_content_language);
641        }
642        if let Some(blob_content_md5) = options.blob_content_md5 {
643            request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
644        }
645        if let Some(blob_content_type) = options.blob_content_type.as_ref() {
646            request.insert_header("x-ms-blob-content-type", blob_content_type);
647        }
648        request.insert_header("x-ms-blob-type", "BlockBlob");
649        request.insert_header("x-ms-copy-source", copy_source);
650        if let Some(copy_source_authorization) = options.copy_source_authorization.as_ref() {
651            request.insert_header("x-ms-copy-source-authorization", copy_source_authorization);
652        }
653        if let Some(copy_source_blob_properties) = options.copy_source_blob_properties {
654            request.insert_header(
655                "x-ms-copy-source-blob-properties",
656                copy_source_blob_properties.to_string(),
657            );
658        }
659        if let Some(copy_source_tags) = options.copy_source_tags.as_ref() {
660            request.insert_header("x-ms-copy-source-tag-option", copy_source_tags.to_string());
661        }
662        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
663            request.insert_header(
664                "x-ms-encryption-algorithm",
665                encryption_algorithm.to_string(),
666            );
667        }
668        if let Some(encryption_key) = options.encryption_key.as_ref() {
669            request.insert_header("x-ms-encryption-key", encryption_key);
670        }
671        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
672            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
673        }
674        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
675            request.insert_header("x-ms-encryption-scope", encryption_scope);
676        }
677        if let Some(file_request_intent) = options.file_request_intent.as_ref() {
678            request.insert_header("x-ms-file-request-intent", file_request_intent.to_string());
679        }
680        if let Some(if_tags) = options.if_tags.as_ref() {
681            request.insert_header("x-ms-if-tags", if_tags);
682        }
683        if let Some(lease_id) = options.lease_id.as_ref() {
684            request.insert_header("x-ms-lease-id", lease_id);
685        }
686        if let Some(metadata) = options.metadata.as_ref() {
687            for (k, v) in metadata {
688                request.insert_header(format!("x-ms-meta-{k}"), v);
689            }
690        }
691        if let Some(source_content_md5) = options.source_content_md5 {
692            request.insert_header(
693                "x-ms-source-content-md5",
694                base64::encode(source_content_md5),
695            );
696        }
697        if let Some(source_encryption_algorithm) = options.source_encryption_algorithm.as_ref() {
698            request.insert_header(
699                "x-ms-source-encryption-algorithm",
700                source_encryption_algorithm.to_string(),
701            );
702        }
703        if let Some(source_encryption_key) = options.source_encryption_key.as_ref() {
704            request.insert_header("x-ms-source-encryption-key", source_encryption_key);
705        }
706        if let Some(source_encryption_key_sha256) = options.source_encryption_key_sha256.as_ref() {
707            request.insert_header(
708                "x-ms-source-encryption-key-sha256",
709                source_encryption_key_sha256,
710            );
711        }
712        if let Some(source_if_match) = options.source_if_match.as_ref() {
713            request.insert_header("x-ms-source-if-match", source_if_match.to_string());
714        }
715        if let Some(source_if_modified_since) = options.source_if_modified_since {
716            request.insert_header(
717                "x-ms-source-if-modified-since",
718                to_rfc7231(&source_if_modified_since),
719            );
720        }
721        if let Some(source_if_none_match) = options.source_if_none_match.as_ref() {
722            request.insert_header(
723                "x-ms-source-if-none-match",
724                source_if_none_match.to_string(),
725            );
726        }
727        if let Some(source_if_tags) = options.source_if_tags.as_ref() {
728            request.insert_header("x-ms-source-if-tags", source_if_tags);
729        }
730        if let Some(source_if_unmodified_since) = options.source_if_unmodified_since {
731            request.insert_header(
732                "x-ms-source-if-unmodified-since",
733                to_rfc7231(&source_if_unmodified_since),
734            );
735        }
736        if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
737            request.insert_header("x-ms-tags", blob_tags_string);
738        }
739        request.insert_header("x-ms-version", &self.version);
740        let rsp = self
741            .pipeline
742            .send(
743                &ctx,
744                &mut request,
745                Some(PipelineSendOptions {
746                    check_success: CheckSuccessOptions {
747                        success_codes: &[201],
748                    },
749                    ..Default::default()
750                }),
751            )
752            .await?;
753        Ok(rsp.into())
754    }
755
756    /// Uploads the content to the specified block blob. If the blob already exists, the data and any existing metadata will be
757    /// overwritten.
758    ///
759    /// # Arguments
760    ///
761    /// * `body` - The body of the request.
762    /// * `content_length` - The length of the request.
763    /// * `options` - Optional parameters for the request.
764    ///
765    /// ## Response Headers
766    ///
767    /// The returned [`Response`](azure_core::http::Response) implements the [`BlockBlobClientUploadInternalResultHeaders`] trait, which provides
768    /// access to response headers. For example:
769    ///
770    /// ```ignore
771    /// use azure_core::{Result, http::{Response, NoFormat}};
772    /// use azure_storage_blob::models::{BlockBlobClientUploadInternalResult, BlockBlobClientUploadInternalResultHeaders};
773    /// async fn example() -> Result<()> {
774    ///     let response: Response<BlockBlobClientUploadInternalResult, NoFormat> = unimplemented!();
775    ///     // Access response headers
776    ///     if let Some(content_md5) = response.content_md5()? {
777    ///         println!("content-md5: {:?}", content_md5);
778    ///     }
779    ///     if let Some(etag) = response.etag()? {
780    ///         println!("etag: {:?}", etag);
781    ///     }
782    ///     if let Some(last_modified) = response.last_modified()? {
783    ///         println!("last-modified: {:?}", last_modified);
784    ///     }
785    ///     Ok(())
786    /// }
787    /// ```
788    ///
789    /// ### Available headers
790    /// * [`content_md5`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::content_md5) - content-md5
791    /// * [`etag`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::etag) - etag
792    /// * [`last_modified`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::last_modified) - last-modified
793    /// * [`content_crc64`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::content_crc64) - x-ms-content-crc64
794    /// * [`encryption_key_sha256`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::encryption_key_sha256) - x-ms-encryption-key-sha256
795    /// * [`encryption_scope`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::encryption_scope) - x-ms-encryption-scope
796    /// * [`is_server_encrypted`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::is_server_encrypted) - x-ms-request-server-encrypted
797    /// * [`version_id`()](crate::generated::models::BlockBlobClientUploadInternalResultHeaders::version_id) - x-ms-version-id
798    ///
799    /// [`BlockBlobClientUploadInternalResultHeaders`]: crate::generated::models::BlockBlobClientUploadInternalResultHeaders
800    #[tracing::function("Storage.Blob.BlockBlobClient.upload")]
801    pub(crate) async fn upload_internal(
802        &self,
803        body: RequestContent<Bytes, NoFormat>,
804        content_length: u64,
805        options: Option<BlockBlobClientUploadInternalOptions<'_>>,
806    ) -> Result<Response<BlockBlobClientUploadInternalResult, NoFormat>> {
807        let options = options.unwrap_or_default();
808        let ctx = options.method_options.context.to_borrowed();
809        let mut url = self.endpoint.clone();
810        let mut query_builder = url.query_builder();
811        if let Some(timeout) = options.timeout {
812            query_builder.set_pair("timeout", timeout.to_string());
813        }
814        query_builder.build();
815        let mut request = Request::new(url, Method::Put);
816        request.insert_header("content-length", content_length.to_string());
817        if let Some(transactional_content_md5) = options.transactional_content_md5 {
818            request.insert_header("content-md5", base64::encode(transactional_content_md5));
819        }
820        request.insert_header("content-type", "application/octet-stream");
821        if let Some(if_match) = options.if_match.as_ref() {
822            request.insert_header("if-match", if_match.to_string());
823        }
824        if let Some(if_modified_since) = options.if_modified_since {
825            request.insert_header("if-modified-since", to_rfc7231(&if_modified_since));
826        }
827        if let Some(if_none_match) = options.if_none_match.as_ref() {
828            request.insert_header("if-none-match", if_none_match.to_string());
829        }
830        if let Some(if_unmodified_since) = options.if_unmodified_since {
831            request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since));
832        }
833        if let Some(tier) = options.tier.as_ref() {
834            request.insert_header("x-ms-access-tier", tier.to_string());
835        }
836        if let Some(blob_cache_control) = options.blob_cache_control.as_ref() {
837            request.insert_header("x-ms-blob-cache-control", blob_cache_control);
838        }
839        if let Some(blob_content_disposition) = options.blob_content_disposition.as_ref() {
840            request.insert_header("x-ms-blob-content-disposition", blob_content_disposition);
841        }
842        if let Some(blob_content_encoding) = options.blob_content_encoding.as_ref() {
843            request.insert_header("x-ms-blob-content-encoding", blob_content_encoding);
844        }
845        if let Some(blob_content_language) = options.blob_content_language.as_ref() {
846            request.insert_header("x-ms-blob-content-language", blob_content_language);
847        }
848        if let Some(blob_content_md5) = options.blob_content_md5 {
849            request.insert_header("x-ms-blob-content-md5", base64::encode(blob_content_md5));
850        }
851        if let Some(blob_content_type) = options.blob_content_type.as_ref() {
852            request.insert_header("x-ms-blob-content-type", blob_content_type);
853        }
854        request.insert_header("x-ms-blob-type", "BlockBlob");
855        if let Some(transactional_content_crc64) = options.transactional_content_crc64 {
856            request.insert_header(
857                "x-ms-content-crc64",
858                base64::encode(transactional_content_crc64),
859            );
860        }
861        if let Some(encryption_algorithm) = options.encryption_algorithm.as_ref() {
862            request.insert_header(
863                "x-ms-encryption-algorithm",
864                encryption_algorithm.to_string(),
865            );
866        }
867        if let Some(encryption_key) = options.encryption_key.as_ref() {
868            request.insert_header("x-ms-encryption-key", encryption_key);
869        }
870        if let Some(encryption_key_sha256) = options.encryption_key_sha256.as_ref() {
871            request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256);
872        }
873        if let Some(encryption_scope) = options.encryption_scope.as_ref() {
874            request.insert_header("x-ms-encryption-scope", encryption_scope);
875        }
876        if let Some(if_tags) = options.if_tags.as_ref() {
877            request.insert_header("x-ms-if-tags", if_tags);
878        }
879        if let Some(immutability_policy_mode) = options.immutability_policy_mode.as_ref() {
880            request.insert_header(
881                "x-ms-immutability-policy-mode",
882                immutability_policy_mode.to_string(),
883            );
884        }
885        if let Some(immutability_policy_expiry) = options.immutability_policy_expiry {
886            request.insert_header(
887                "x-ms-immutability-policy-until-date",
888                to_rfc7231(&immutability_policy_expiry),
889            );
890        }
891        if let Some(lease_id) = options.lease_id.as_ref() {
892            request.insert_header("x-ms-lease-id", lease_id);
893        }
894        if let Some(legal_hold) = options.legal_hold {
895            request.insert_header("x-ms-legal-hold", legal_hold.to_string());
896        }
897        if let Some(metadata) = options.metadata.as_ref() {
898            for (k, v) in metadata {
899                request.insert_header(format!("x-ms-meta-{k}"), v);
900            }
901        }
902        if let Some(structured_body_type) = options.structured_body_type.as_ref() {
903            request.insert_header("x-ms-structured-body", structured_body_type);
904        }
905        if let Some(structured_content_length) = options.structured_content_length {
906            request.insert_header(
907                "x-ms-structured-content-length",
908                structured_content_length.to_string(),
909            );
910        }
911        if let Some(blob_tags_string) = options.blob_tags_string.as_ref() {
912            request.insert_header("x-ms-tags", blob_tags_string);
913        }
914        request.insert_header("x-ms-version", &self.version);
915        request.set_body(body);
916        let rsp = self
917            .pipeline
918            .send(
919                &ctx,
920                &mut request,
921                Some(PipelineSendOptions {
922                    check_success: CheckSuccessOptions {
923                        success_codes: &[201],
924                    },
925                    ..Default::default()
926                }),
927            )
928            .await?;
929        Ok(rsp.into())
930    }
931}
932
933/// Default value for [`BlockBlobClientOptions::version`].
934pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
935
936impl Default for BlockBlobClientOptions {
937    fn default() -> Self {
938        Self {
939            client_options: ClientOptions::default(),
940            version: String::from(DEFAULT_VERSION),
941        }
942    }
943}