use crate::models::{
AccessPolicy, AppendBlobClientCreateOptions, BlobTag, BlobTags,
BlockBlobClientCommitBlockListOptions, BlockBlobClientUploadBlobFromUrlOptions,
BlockBlobClientUploadOptions, PageBlobClientCreateOptions, SignedIdentifier, SignedIdentifiers,
};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use std::collections::HashMap;
pub(crate) fn encode_tags(tags: &BlobTags) -> Option<String> {
let result = match &tags.blob_tag_set {
Some(tag_set) => tag_set
.iter()
.filter_map(|tag| match (&tag.key, &tag.value) {
(Some(k), Some(v)) => {
let encoded_key = percent_encode(k.as_bytes(), NON_ALPHANUMERIC);
let encoded_value = percent_encode(v.as_bytes(), NON_ALPHANUMERIC);
Some(format!("{}={}", encoded_key, encoded_value))
}
_ => None,
})
.collect::<Vec<_>>()
.join("&"),
None => String::new(),
};
if result.is_empty() {
None
} else {
Some(result)
}
}
impl PageBlobClientCreateOptions<'_> {
pub fn if_not_exists(self) -> Self {
Self {
if_none_match: Some("*".into()),
..self
}
}
}
impl AppendBlobClientCreateOptions<'_> {
pub fn if_not_exists(self) -> Self {
Self {
if_none_match: Some("*".into()),
..self
}
}
}
impl BlockBlobClientUploadBlobFromUrlOptions<'_> {
pub fn if_not_exists(self) -> Self {
Self {
if_none_match: Some("*".into()),
..self
}
}
}
impl BlockBlobClientUploadOptions<'_> {
pub fn if_not_exists(self) -> Self {
Self {
if_none_match: Some("*".into()),
..self
}
}
}
impl PageBlobClientCreateOptions<'_> {
pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
self.blob_tags_string = encode_tags(&tags.into());
self
}
}
impl AppendBlobClientCreateOptions<'_> {
pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
self.blob_tags_string = encode_tags(&tags.into());
self
}
}
impl BlockBlobClientUploadBlobFromUrlOptions<'_> {
pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
self.blob_tags_string = encode_tags(&tags.into());
self
}
}
impl BlockBlobClientUploadOptions<'_> {
pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
self.blob_tags_string = encode_tags(&tags.into());
self
}
}
impl BlockBlobClientCommitBlockListOptions<'_> {
pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
self.blob_tags_string = encode_tags(&tags.into());
self
}
}
impl From<BlobTags> for HashMap<String, String> {
fn from(blob_tags: BlobTags) -> Self {
let mut map = HashMap::new();
if let Some(tags) = blob_tags.blob_tag_set {
for tag in tags {
if let (Some(key), Some(value)) = (tag.key, tag.value) {
map.insert(key, value);
}
}
}
map
}
}
impl From<HashMap<String, String>> for BlobTags {
fn from(tags: HashMap<String, String>) -> Self {
let blob_tags = tags
.into_iter()
.map(|(k, v)| BlobTag {
key: Some(k),
value: Some(v),
})
.collect();
BlobTags {
blob_tag_set: Some(blob_tags),
}
}
}
impl From<HashMap<String, AccessPolicy>> for SignedIdentifiers {
fn from(policies: HashMap<String, AccessPolicy>) -> Self {
if policies.is_empty() {
return SignedIdentifiers { items: None };
}
let signed_identifiers: Vec<SignedIdentifier> = policies
.into_iter()
.map(|(id, access_policy)| SignedIdentifier {
id: Some(id),
access_policy: Some(access_policy),
})
.collect();
SignedIdentifiers {
items: Some(signed_identifiers),
}
}
}