azure_storage_blob/models/
extensions.rs1use crate::models::{
5 AccessPolicy, AppendBlobClientCreateOptions, BlobTag, BlobTags,
6 BlockBlobClientCommitBlockListOptions, BlockBlobClientUploadBlobFromUrlOptions,
7 BlockBlobClientUploadOptions, PageBlobClientCreateOptions, SignedIdentifier, SignedIdentifiers,
8};
9use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
10use std::collections::HashMap;
11
12pub(crate) fn encode_tags(tags: &BlobTags) -> Option<String> {
17 let result = match &tags.blob_tag_set {
18 Some(tag_set) => tag_set
19 .iter()
20 .filter_map(|tag| match (&tag.key, &tag.value) {
21 (Some(k), Some(v)) => {
22 let encoded_key = percent_encode(k.as_bytes(), NON_ALPHANUMERIC);
23 let encoded_value = percent_encode(v.as_bytes(), NON_ALPHANUMERIC);
24 Some(format!("{}={}", encoded_key, encoded_value))
25 }
26 _ => None,
27 })
28 .collect::<Vec<_>>()
29 .join("&"),
30 None => String::new(),
31 };
32 if result.is_empty() {
33 None
34 } else {
35 Some(result)
36 }
37}
38
39impl PageBlobClientCreateOptions<'_> {
44 pub fn if_not_exists(self) -> Self {
45 Self {
46 if_none_match: Some("*".into()),
47 ..self
48 }
49 }
50}
51
52impl AppendBlobClientCreateOptions<'_> {
57 pub fn if_not_exists(self) -> Self {
58 Self {
59 if_none_match: Some("*".into()),
60 ..self
61 }
62 }
63}
64
65impl BlockBlobClientUploadBlobFromUrlOptions<'_> {
70 pub fn if_not_exists(self) -> Self {
71 Self {
72 if_none_match: Some("*".into()),
73 ..self
74 }
75 }
76}
77
78impl BlockBlobClientUploadOptions<'_> {
83 pub fn if_not_exists(self) -> Self {
84 Self {
85 if_none_match: Some("*".into()),
86 ..self
87 }
88 }
89}
90
91impl PageBlobClientCreateOptions<'_> {
95 pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
96 self.blob_tags_string = encode_tags(&tags.into());
97 self
98 }
99}
100
101impl AppendBlobClientCreateOptions<'_> {
102 pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
103 self.blob_tags_string = encode_tags(&tags.into());
104 self
105 }
106}
107
108impl BlockBlobClientUploadBlobFromUrlOptions<'_> {
109 pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
110 self.blob_tags_string = encode_tags(&tags.into());
111 self
112 }
113}
114
115impl BlockBlobClientUploadOptions<'_> {
116 pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
117 self.blob_tags_string = encode_tags(&tags.into());
118 self
119 }
120}
121
122impl BlockBlobClientCommitBlockListOptions<'_> {
123 pub fn with_tags(mut self, tags: impl Into<BlobTags>) -> Self {
124 self.blob_tags_string = encode_tags(&tags.into());
125 self
126 }
127}
128
129impl From<BlobTags> for HashMap<String, String> {
131 fn from(blob_tags: BlobTags) -> Self {
132 let mut map = HashMap::new();
133
134 if let Some(tags) = blob_tags.blob_tag_set {
135 for tag in tags {
136 if let (Some(key), Some(value)) = (tag.key, tag.value) {
137 map.insert(key, value);
138 }
139 }
140 }
141 map
142 }
143}
144
145impl From<HashMap<String, String>> for BlobTags {
147 fn from(tags: HashMap<String, String>) -> Self {
148 let blob_tags = tags
149 .into_iter()
150 .map(|(k, v)| BlobTag {
151 key: Some(k),
152 value: Some(v),
153 })
154 .collect();
155 BlobTags {
156 blob_tag_set: Some(blob_tags),
157 }
158 }
159}
160
161impl From<HashMap<String, AccessPolicy>> for SignedIdentifiers {
163 fn from(policies: HashMap<String, AccessPolicy>) -> Self {
164 if policies.is_empty() {
165 return SignedIdentifiers { items: None };
166 }
167
168 let signed_identifiers: Vec<SignedIdentifier> = policies
169 .into_iter()
170 .map(|(id, access_policy)| SignedIdentifier {
171 id: Some(id),
172 access_policy: Some(access_policy),
173 })
174 .collect();
175
176 SignedIdentifiers {
177 items: Some(signed_identifiers),
178 }
179 }
180}