Skip to content

Commit b258df2

Browse files
authored
Move optional de/serializers for base64 bytes to base64::option (Azure#3214)
Resolves Azure#3213, making `base64` congruent with `time`.
1 parent 112cf31 commit b258df2

File tree

9 files changed

+145
-34
lines changed

9 files changed

+145
-34
lines changed

.vscode/cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"cppvsdbg",
4343
"datalake",
4444
"datetime",
45+
"deserializers",
4546
"devicecode",
4647
"docsrs",
4748
"doctest",

sdk/core/azure_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
### Breaking Changes
88

9+
- Moved deserializers and serializers for optional base64-encoded bytes to `base64::option` module. `base64` module now deserializes or serializes non-optional fields congruent with the `time` module.
910
- Removed `constants` module.
1011
- Removed `CustomHeaders` policy.
1112
- Removed `ErrorKind::MockFramework`.

sdk/core/azure_core/benches/deserialization.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,9 @@ mod models {
242242
/// The content MD5 of the blob.
243243
#[serde(
244244
default,
245-
deserialize_with = "azure_core::base64::deserialize",
245+
deserialize_with = "azure_core::base64::option::deserialize",
246246
rename = "Content-MD5",
247-
serialize_with = "azure_core::base64::serialize",
247+
serialize_with = "azure_core::base64::option::serialize",
248248
skip_serializing_if = "Option::is_none"
249249
)]
250250
pub content_md5: Option<Vec<u8>>,

sdk/core/typespec_client_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
### Breaking Changes
88

9+
- Moved deserializers and serializers for optional base64-encoded bytes to `base64::option` module. `base64` module now deserializes or serializes non-optional fields congruent with the `time` module.
910
- Removed `CustomHeaders` policy.
1011
- Removed `ErrorKind::MockFramework`.
1112

sdk/core/typespec_client_core/src/base64.rs

Lines changed: 136 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,15 @@ where
128128
/// #[derive(Deserialize)]
129129
/// struct SomeType {
130130
/// #[serde(deserialize_with = "base64::deserialize")]
131-
/// pub value: Option<Vec<u8>>,
131+
/// pub value: Vec<u8>,
132132
/// }
133133
/// ```
134-
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
134+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
135135
where
136136
D: Deserializer<'de>,
137137
{
138-
let decoded = <Option<String>>::deserialize(deserializer)?;
139-
match decoded {
140-
Some(d) => {
141-
let d = decode(d).map_err(serde::de::Error::custom)?;
142-
Ok(Some(d))
143-
}
144-
None => Ok(None),
145-
}
138+
let decoded = String::deserialize(deserializer)?;
139+
decode(decoded).map_err(serde::de::Error::custom)
146140
}
147141

148142
/// Helper that can be used in a serde deserialize_with derive macro
@@ -158,21 +152,15 @@ where
158152
/// #[derive(Deserialize)]
159153
/// struct SomeType {
160154
/// #[serde(deserialize_with = "base64::deserialize_url_safe")]
161-
/// pub value: Option<Vec<u8>>,
155+
/// pub value: Vec<u8>,
162156
/// }
163157
/// ```
164-
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
158+
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
165159
where
166160
D: Deserializer<'de>,
167161
{
168-
let decoded = <Option<String>>::deserialize(deserializer)?;
169-
match decoded {
170-
Some(d) => {
171-
let d = decode_url_safe(d).map_err(serde::de::Error::custom)?;
172-
Ok(Some(d))
173-
}
174-
None => Ok(None),
175-
}
162+
let decoded = String::deserialize(deserializer)?;
163+
decode_url_safe(decoded).map_err(serde::de::Error::custom)
176164
}
177165

178166
/// Helper that can be used in a serde serialize_with derive macro
@@ -188,16 +176,16 @@ where
188176
/// #[derive(Serialize)]
189177
/// struct SomeType {
190178
/// #[serde(serialize_with = "base64::serialize")]
191-
/// pub value: Option<Vec<u8>>,
179+
/// pub value: Vec<u8>,
192180
/// }
193181
/// ```
194-
pub fn serialize<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
182+
pub fn serialize<S, T>(to_serialize: &T, serializer: S) -> Result<S::Ok, S::Error>
195183
where
196184
S: Serializer,
197185
T: AsRef<[u8]>,
198186
{
199-
let encoded = to_serialize.as_ref().map(encode);
200-
<Option<String>>::serialize(&encoded, serializer)
187+
let encoded = encode(to_serialize.as_ref());
188+
String::serialize(&encoded, serializer)
201189
}
202190

203191
/// Helper that can be used in a serde serialize_with derive macro
@@ -213,14 +201,134 @@ where
213201
/// #[derive(Serialize)]
214202
/// struct SomeType {
215203
/// #[serde(serialize_with = "base64::serialize_url_safe")]
216-
/// pub value: Option<Vec<u8>>,
204+
/// pub value: Vec<u8>,
217205
/// }
218206
/// ```
219-
pub fn serialize_url_safe<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
207+
pub fn serialize_url_safe<S, T>(to_serialize: &T, serializer: S) -> Result<S::Ok, S::Error>
220208
where
221209
S: Serializer,
222210
T: AsRef<[u8]>,
223211
{
224-
let encoded = to_serialize.as_ref().map(encode_url_safe);
225-
<Option<String>>::serialize(&encoded, serializer)
212+
let encoded = encode_url_safe(to_serialize.as_ref());
213+
String::serialize(&encoded, serializer)
214+
}
215+
216+
pub mod option {
217+
//! Serialization helpers for optional fields.
218+
219+
use super::{decode, decode_url_safe, encode, encode_url_safe};
220+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
221+
222+
/// Helper that can be used in a serde deserialize_with derive macro
223+
/// for struct fields that contain base64 encoded data.
224+
///
225+
/// Uses the standard base64 decoder.
226+
///
227+
/// # Examples
228+
///
229+
/// ```rust,no_run
230+
/// # use serde::{Deserialize};
231+
/// # use typespec_client_core::base64;
232+
/// #[derive(Deserialize)]
233+
/// struct SomeType {
234+
/// #[serde(deserialize_with = "base64::option::deserialize")]
235+
/// pub value: Option<Vec<u8>>,
236+
/// }
237+
/// ```
238+
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
239+
where
240+
D: Deserializer<'de>,
241+
{
242+
let decoded = <Option<String>>::deserialize(deserializer)?;
243+
match decoded {
244+
Some(d) => {
245+
let d = decode(d).map_err(serde::de::Error::custom)?;
246+
Ok(Some(d))
247+
}
248+
None => Ok(None),
249+
}
250+
}
251+
252+
/// Helper that can be used in a serde deserialize_with derive macro
253+
/// for struct fields that contain base64 encoded data.
254+
///
255+
/// Uses the URL safe base64 decoder.
256+
///
257+
/// # Examples
258+
///
259+
/// ```rust,no_run
260+
/// # use serde::{Deserialize};
261+
/// # use typespec_client_core::base64;
262+
/// #[derive(Deserialize)]
263+
/// struct SomeType {
264+
/// #[serde(deserialize_with = "base64::option::deserialize_url_safe")]
265+
/// pub value: Option<Vec<u8>>,
266+
/// }
267+
/// ```
268+
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
269+
where
270+
D: Deserializer<'de>,
271+
{
272+
let decoded = <Option<String>>::deserialize(deserializer)?;
273+
match decoded {
274+
Some(d) => {
275+
let d = decode_url_safe(d).map_err(serde::de::Error::custom)?;
276+
Ok(Some(d))
277+
}
278+
None => Ok(None),
279+
}
280+
}
281+
282+
/// Helper that can be used in a serde serialize_with derive macro
283+
/// for struct fields that contain base64 encoded data.
284+
///
285+
/// Uses the standard base64 encoder.
286+
///
287+
/// # Examples
288+
///
289+
/// ```rust,no_run
290+
/// # use serde::{Serialize};
291+
/// # use typespec_client_core::base64;
292+
/// #[derive(Serialize)]
293+
/// struct SomeType {
294+
/// #[serde(serialize_with = "base64::option::serialize")]
295+
/// pub value: Option<Vec<u8>>,
296+
/// }
297+
/// ```
298+
pub fn serialize<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
299+
where
300+
S: Serializer,
301+
T: AsRef<[u8]>,
302+
{
303+
let encoded = to_serialize.as_ref().map(encode);
304+
<Option<String>>::serialize(&encoded, serializer)
305+
}
306+
307+
/// Helper that can be used in a serde serialize_with derive macro
308+
/// for struct fields that contain base64 encoded data.
309+
///
310+
/// Uses the URL safe base64 encoder.
311+
///
312+
/// # Examples
313+
///
314+
/// ```rust,no_run
315+
/// # use serde::{Serialize};
316+
/// # use typespec_client_core::base64;
317+
/// #[derive(Serialize)]
318+
/// struct SomeType {
319+
/// #[serde(serialize_with = "base64::option::serialize_url_safe")]
320+
/// pub value: Option<Vec<u8>>,
321+
/// }
322+
/// ```
323+
pub fn serialize_url_safe<S, T>(
324+
to_serialize: &Option<T>,
325+
serializer: S,
326+
) -> Result<S::Ok, S::Error>
327+
where
328+
S: Serializer,
329+
T: AsRef<[u8]>,
330+
{
331+
let encoded = to_serialize.as_ref().map(encode_url_safe);
332+
<Option<String>>::serialize(&encoded, serializer)
333+
}
226334
}

sdk/keyvault/azure_security_keyvault_certificates/src/generated/models/pub_models.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/keyvault/azure_security_keyvault_keys/src/generated/models/pub_models.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/keyvault/azure_security_keyvault_secrets/src/generated/models/pub_models.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/storage/azure_storage_blob/src/generated/models/pub_models.rs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)