azure_storage_blob/clients/
blob_service_client.rs1pub use crate::generated::clients::{BlobServiceClient, BlobServiceClientOptions};
5
6use crate::{BlobClient, BlobContainerClient};
7use azure_core::{
8 credentials::TokenCredential,
9 http::{
10 policies::{auth::BearerTokenAuthorizationPolicy, Policy},
11 Pipeline, Url,
12 },
13 tracing, Result,
14};
15use std::sync::Arc;
16
17impl BlobServiceClient {
18 #[tracing::new("Storage.Blob.Service")]
27 pub fn new(
28 service_url: Url,
29 credential: Option<Arc<dyn TokenCredential>>,
30 options: Option<BlobServiceClientOptions>,
31 ) -> Result<Self> {
32 if service_url.cannot_be_a_base() {
34 return Err(azure_core::Error::with_message(
35 azure_core::error::ErrorKind::Other,
36 format!("{service_url} is not a valid base URL"),
37 ));
38 }
39 let mut options = options.unwrap_or_default();
40 super::apply_client_defaults(&mut options.client_options);
41
42 let mut per_retry_policies: Vec<Arc<dyn Policy>> = Vec::default();
43 if let Some(token_credential) = credential {
44 if !service_url.scheme().starts_with("https") {
45 return Err(azure_core::Error::with_message(
46 azure_core::error::ErrorKind::Other,
47 format!("{service_url} must use https"),
48 ));
49 }
50 per_retry_policies.push(Arc::new(BearerTokenAuthorizationPolicy::new(
51 token_credential,
52 vec!["https://storage.azure.com/.default"],
53 )));
54 }
55
56 let pipeline = Pipeline::new(
57 option_env!("CARGO_PKG_NAME"),
58 option_env!("CARGO_PKG_VERSION"),
59 options.client_options.clone(),
60 Vec::default(),
61 per_retry_policies,
62 None,
63 );
64
65 Ok(Self {
66 endpoint: service_url,
67 version: options.version,
68 pipeline,
69 })
70 }
71
72 pub fn blob_container_client(&self, container_name: &str) -> BlobContainerClient {
78 let mut container_url = self.url().clone();
79 container_url
80 .path_segments_mut()
81 .expect("Cannot be a base URL.")
83 .push(container_name);
84
85 BlobContainerClient {
86 endpoint: container_url,
87 pipeline: self.pipeline.clone(),
88 version: self.version.clone(),
89 tracer: self.tracer.clone(),
90 }
91 }
92
93 pub fn blob_client(&self, container_name: &str, blob_name: &str) -> BlobClient {
100 let mut blob_url = self.url().clone();
101 blob_url
102 .path_segments_mut()
103 .expect("Cannot be a base URL.")
105 .extend([container_name, blob_name]);
106
107 BlobClient {
108 endpoint: blob_url,
109 pipeline: self.pipeline.clone(),
110 version: self.version.clone(),
111 tracer: self.tracer.clone(),
112 }
113 }
114
115 pub fn url(&self) -> &Url {
117 &self.endpoint
118 }
119}