Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"cppvsdbg",
"datalake",
"datetime",
"deserializers",
"devicecode",
"docsrs",
"doctest",
Expand Down
1 change: 1 addition & 0 deletions sdk/core/azure_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Breaking Changes

- 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.
- Removed `constants` module.
- Removed `CustomHeaders` policy.
- Removed `ErrorKind::MockFramework`.
Expand Down
4 changes: 2 additions & 2 deletions sdk/core/azure_core/benches/deserialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ mod models {
/// The content MD5 of the blob.
#[serde(
default,
deserialize_with = "azure_core::base64::deserialize",
deserialize_with = "azure_core::base64::option::deserialize",
rename = "Content-MD5",
serialize_with = "azure_core::base64::serialize",
serialize_with = "azure_core::base64::option::serialize",
skip_serializing_if = "Option::is_none"
)]
pub content_md5: Option<Vec<u8>>,
Expand Down
1 change: 1 addition & 0 deletions sdk/core/typespec_client_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Breaking Changes

- 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.
- Removed `CustomHeaders` policy.
- Removed `ErrorKind::MockFramework`.

Expand Down
164 changes: 136 additions & 28 deletions sdk/core/typespec_client_core/src/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,15 @@ where
/// #[derive(Deserialize)]
/// struct SomeType {
/// #[serde(deserialize_with = "base64::deserialize")]
/// pub value: Option<Vec<u8>>,
/// pub value: Vec<u8>,
/// }
/// ```
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let decoded = <Option<String>>::deserialize(deserializer)?;
match decoded {
Some(d) => {
let d = decode(d).map_err(serde::de::Error::custom)?;
Ok(Some(d))
}
None => Ok(None),
}
let decoded = String::deserialize(deserializer)?;
decode(decoded).map_err(serde::de::Error::custom)
}

/// Helper that can be used in a serde deserialize_with derive macro
Expand All @@ -158,21 +152,15 @@ where
/// #[derive(Deserialize)]
/// struct SomeType {
/// #[serde(deserialize_with = "base64::deserialize_url_safe")]
/// pub value: Option<Vec<u8>>,
/// pub value: Vec<u8>,
/// }
/// ```
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let decoded = <Option<String>>::deserialize(deserializer)?;
match decoded {
Some(d) => {
let d = decode_url_safe(d).map_err(serde::de::Error::custom)?;
Ok(Some(d))
}
None => Ok(None),
}
let decoded = String::deserialize(deserializer)?;
decode_url_safe(decoded).map_err(serde::de::Error::custom)
}

/// Helper that can be used in a serde serialize_with derive macro
Expand All @@ -188,16 +176,16 @@ where
/// #[derive(Serialize)]
/// struct SomeType {
/// #[serde(serialize_with = "base64::serialize")]
/// pub value: Option<Vec<u8>>,
/// pub value: Vec<u8>,
/// }
/// ```
pub fn serialize<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
pub fn serialize<S, T>(to_serialize: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
let encoded = to_serialize.as_ref().map(encode);
<Option<String>>::serialize(&encoded, serializer)
let encoded = encode(to_serialize.as_ref());
String::serialize(&encoded, serializer)
}

/// Helper that can be used in a serde serialize_with derive macro
Expand All @@ -213,14 +201,134 @@ where
/// #[derive(Serialize)]
/// struct SomeType {
/// #[serde(serialize_with = "base64::serialize_url_safe")]
/// pub value: Option<Vec<u8>>,
/// pub value: Vec<u8>,
/// }
/// ```
pub fn serialize_url_safe<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
pub fn serialize_url_safe<S, T>(to_serialize: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
let encoded = to_serialize.as_ref().map(encode_url_safe);
<Option<String>>::serialize(&encoded, serializer)
let encoded = encode_url_safe(to_serialize.as_ref());
String::serialize(&encoded, serializer)
}

pub mod option {
//! Serialization helpers for optional fields.

use super::{decode, decode_url_safe, encode, encode_url_safe};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// Helper that can be used in a serde deserialize_with derive macro
/// for struct fields that contain base64 encoded data.
///
/// Uses the standard base64 decoder.
///
/// # Examples
///
/// ```rust,no_run
/// # use serde::{Deserialize};
/// # use typespec_client_core::base64;
/// #[derive(Deserialize)]
/// struct SomeType {
/// #[serde(deserialize_with = "base64::option::deserialize")]
/// pub value: Option<Vec<u8>>,
/// }
/// ```
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let decoded = <Option<String>>::deserialize(deserializer)?;
match decoded {
Some(d) => {
let d = decode(d).map_err(serde::de::Error::custom)?;
Ok(Some(d))
}
None => Ok(None),
}
}

/// Helper that can be used in a serde deserialize_with derive macro
/// for struct fields that contain base64 encoded data.
///
/// Uses the URL safe base64 decoder.
///
/// # Examples
///
/// ```rust,no_run
/// # use serde::{Deserialize};
/// # use typespec_client_core::base64;
/// #[derive(Deserialize)]
/// struct SomeType {
/// #[serde(deserialize_with = "base64::option::deserialize_url_safe")]
/// pub value: Option<Vec<u8>>,
/// }
/// ```
pub fn deserialize_url_safe<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let decoded = <Option<String>>::deserialize(deserializer)?;
match decoded {
Some(d) => {
let d = decode_url_safe(d).map_err(serde::de::Error::custom)?;
Ok(Some(d))
}
None => Ok(None),
}
}

/// Helper that can be used in a serde serialize_with derive macro
/// for struct fields that contain base64 encoded data.
///
/// Uses the standard base64 encoder.
///
/// # Examples
///
/// ```rust,no_run
/// # use serde::{Serialize};
/// # use typespec_client_core::base64;
/// #[derive(Serialize)]
/// struct SomeType {
/// #[serde(serialize_with = "base64::option::serialize")]
/// pub value: Option<Vec<u8>>,
/// }
/// ```
pub fn serialize<S, T>(to_serialize: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
let encoded = to_serialize.as_ref().map(encode);
<Option<String>>::serialize(&encoded, serializer)
}

/// Helper that can be used in a serde serialize_with derive macro
/// for struct fields that contain base64 encoded data.
///
/// Uses the URL safe base64 encoder.
///
/// # Examples
///
/// ```rust,no_run
/// # use serde::{Serialize};
/// # use typespec_client_core::base64;
/// #[derive(Serialize)]
/// struct SomeType {
/// #[serde(serialize_with = "base64::option::serialize_url_safe")]
/// pub value: Option<Vec<u8>>,
/// }
/// ```
pub fn serialize_url_safe<S, T>(
to_serialize: &Option<T>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
let encoded = to_serialize.as_ref().map(encode_url_safe);
<Option<String>>::serialize(&encoded, serializer)
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.