use crate::generated::models::{
BlobServiceClientFindBlobsByTagsOptions, BlobServiceClientGetAccountInfoOptions,
BlobServiceClientGetAccountInfoResult, BlobServiceClientGetPropertiesOptions,
BlobServiceClientGetStatisticsOptions, BlobServiceClientListContainersOptions,
BlobServiceClientSetPropertiesOptions, BlobServiceProperties, FilterBlobSegment,
ListContainersSegmentResponse, StorageServiceStats,
};
use azure_core::{
error::CheckSuccessOptions,
fmt::SafeDebug,
http::{
pager::{PagerContinuation, PagerResult, PagerState},
ClientOptions, Method, NoFormat, Pager, Pipeline, PipelineSendOptions, RawResponse,
Request, RequestContent, Response, Url, UrlExt, XmlFormat,
},
tracing, xml, Result,
};
#[tracing::client]
pub struct BlobServiceClient {
pub(crate) endpoint: Url,
pub(crate) pipeline: Pipeline,
pub(crate) version: String,
}
#[derive(Clone, SafeDebug)]
pub struct BlobServiceClientOptions {
pub client_options: ClientOptions,
pub version: String,
}
impl BlobServiceClient {
pub fn endpoint(&self) -> &Url {
&self.endpoint
}
#[tracing::function("Storage.Blob.BlobServiceClient.findBlobsByTags")]
pub async fn find_blobs_by_tags(
&self,
filter_expression: &str,
options: Option<BlobServiceClientFindBlobsByTagsOptions<'_>>,
) -> Result<Response<FilterBlobSegment, XmlFormat>> {
let options = options.unwrap_or_default();
let ctx = options.method_options.context.to_borrowed();
let mut url = self.endpoint.clone();
let mut query_builder = url.query_builder();
query_builder.append_pair("comp", "blobs");
if let Some(include) = options.include.as_ref() {
query_builder.set_pair(
"include",
include
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(","),
);
}
if let Some(marker) = options.marker.as_ref() {
query_builder.set_pair("marker", marker);
}
if let Some(maxresults) = options.maxresults {
query_builder.set_pair("maxresults", maxresults.to_string());
}
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.set_pair("where", filter_expression);
query_builder.build();
let mut request = Request::new(url, Method::Get);
request.insert_header("accept", "application/xml");
request.insert_header("x-ms-version", &self.version);
let rsp = self
.pipeline
.send(
&ctx,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[200],
},
..Default::default()
}),
)
.await?;
Ok(rsp.into())
}
#[tracing::function("Storage.Blob.BlobServiceClient.getAccountInfo")]
pub async fn get_account_info(
&self,
options: Option<BlobServiceClientGetAccountInfoOptions<'_>>,
) -> Result<Response<BlobServiceClientGetAccountInfoResult, NoFormat>> {
let options = options.unwrap_or_default();
let ctx = options.method_options.context.to_borrowed();
let mut url = self.endpoint.clone();
let mut query_builder = url.query_builder();
query_builder
.append_pair("comp", "properties")
.append_pair("restype", "account");
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.build();
let mut request = Request::new(url, Method::Get);
request.insert_header("x-ms-version", &self.version);
let rsp = self
.pipeline
.send(
&ctx,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[200],
},
..Default::default()
}),
)
.await?;
Ok(rsp.into())
}
#[tracing::function("Storage.Blob.BlobServiceClient.getProperties")]
pub async fn get_properties(
&self,
options: Option<BlobServiceClientGetPropertiesOptions<'_>>,
) -> Result<Response<BlobServiceProperties, XmlFormat>> {
let options = options.unwrap_or_default();
let ctx = options.method_options.context.to_borrowed();
let mut url = self.endpoint.clone();
let mut query_builder = url.query_builder();
query_builder
.append_pair("comp", "properties")
.append_pair("restype", "service");
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.build();
let mut request = Request::new(url, Method::Get);
request.insert_header("accept", "application/xml");
request.insert_header("x-ms-version", &self.version);
let rsp = self
.pipeline
.send(
&ctx,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[200],
},
..Default::default()
}),
)
.await?;
Ok(rsp.into())
}
#[tracing::function("Storage.Blob.BlobServiceClient.getStatistics")]
pub async fn get_statistics(
&self,
options: Option<BlobServiceClientGetStatisticsOptions<'_>>,
) -> Result<Response<StorageServiceStats, XmlFormat>> {
let options = options.unwrap_or_default();
let ctx = options.method_options.context.to_borrowed();
let mut url = self.endpoint.clone();
let mut query_builder = url.query_builder();
query_builder
.append_pair("comp", "stats")
.append_pair("restype", "service");
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.build();
let mut request = Request::new(url, Method::Get);
request.insert_header("accept", "application/xml");
request.insert_header("x-ms-version", &self.version);
let rsp = self
.pipeline
.send(
&ctx,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[200],
},
..Default::default()
}),
)
.await?;
Ok(rsp.into())
}
#[tracing::function("Storage.Blob.BlobServiceClient.listContainers")]
pub fn list_containers(
&self,
options: Option<BlobServiceClientListContainersOptions<'_>>,
) -> Result<Pager<ListContainersSegmentResponse, XmlFormat>> {
let options = options.unwrap_or_default().into_owned();
let pipeline = self.pipeline.clone();
let mut first_url = self.endpoint.clone();
let mut query_builder = first_url.query_builder();
query_builder.append_pair("comp", "list");
if let Some(include) = options.include.as_ref() {
query_builder.set_pair(
"include",
include
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(","),
);
}
if let Some(marker) = options.marker.as_ref() {
query_builder.set_pair("marker", marker);
}
if let Some(maxresults) = options.maxresults {
query_builder.set_pair("maxresults", maxresults.to_string());
}
if let Some(prefix) = options.prefix.as_ref() {
query_builder.set_pair("prefix", prefix);
}
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.build();
let version = self.version.clone();
Ok(Pager::new(
move |marker: PagerState, pager_options| {
let mut url = first_url.clone();
if let PagerState::More(marker) = marker {
let mut query_builder = url.query_builder();
query_builder.set_pair("marker", marker.as_ref());
query_builder.build();
}
let mut request = Request::new(url, Method::Get);
request.insert_header("accept", "application/xml");
request.insert_header("x-ms-version", &version);
let pipeline = pipeline.clone();
Box::pin(async move {
let rsp = pipeline
.send(
&pager_options.context,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[200],
},
..Default::default()
}),
)
.await?;
let (status, headers, body) = rsp.deconstruct();
let res: ListContainersSegmentResponse = xml::from_xml(&body)?;
let rsp = RawResponse::from_bytes(status, headers, body).into();
Ok(match res.next_marker {
Some(next_marker) if !next_marker.is_empty() => PagerResult::More {
response: rsp,
continuation: PagerContinuation::Token(next_marker),
},
_ => PagerResult::Done { response: rsp },
})
})
},
Some(options.method_options),
))
}
#[tracing::function("Storage.Blob.BlobServiceClient.setProperties")]
pub async fn set_properties(
&self,
storage_service_properties: RequestContent<BlobServiceProperties, XmlFormat>,
options: Option<BlobServiceClientSetPropertiesOptions<'_>>,
) -> Result<Response<(), NoFormat>> {
let options = options.unwrap_or_default();
let ctx = options.method_options.context.to_borrowed();
let mut url = self.endpoint.clone();
let mut query_builder = url.query_builder();
query_builder
.append_pair("comp", "properties")
.append_pair("restype", "service");
if let Some(timeout) = options.timeout {
query_builder.set_pair("timeout", timeout.to_string());
}
query_builder.build();
let mut request = Request::new(url, Method::Put);
request.insert_header("content-type", "application/xml");
request.insert_header("x-ms-version", &self.version);
request.set_body(storage_service_properties);
let rsp = self
.pipeline
.send(
&ctx,
&mut request,
Some(PipelineSendOptions {
check_success: CheckSuccessOptions {
success_codes: &[202],
},
..Default::default()
}),
)
.await?;
Ok(rsp.into())
}
}
pub(crate) const DEFAULT_VERSION: &str = "2026-04-06";
impl Default for BlobServiceClientOptions {
fn default() -> Self {
Self {
client_options: ClientOptions::default(),
version: String::from(DEFAULT_VERSION),
}
}
}