Skip to content

Commit

Permalink
Make time_zone/formats@1 fully zero-copy (#1676)
Browse files Browse the repository at this point in the history
* Make time_zone/formats@1 fully zero-copy

* fmt
  • Loading branch information
Manishearth authored Mar 8, 2022
1 parent e3d2818 commit df232db
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
4 changes: 4 additions & 0 deletions components/datetime/src/provider/time_zones.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ use zerovec::{ZeroMap, ZeroMap2d};
pub struct TimeZoneFormatsV1<'data> {
/// The hour format for displaying GMT offsets.
#[cfg_attr(feature = "provider_serde", serde(borrow))]
#[cfg_attr(
feature = "provider_serde",
serde(deserialize_with = "icu_provider::serde::borrow_de_utils::tuple_of_cow")
)]
pub hour_format: (Cow<'data, str>, Cow<'data, str>),
/// The localized GMT-offset format.
#[cfg_attr(feature = "provider_serde", serde(borrow))]
Expand Down
22 changes: 22 additions & 0 deletions provider/core/src/serde/borrow_de_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ where
<Option<CowWrap<'de>>>::deserialize(deserializer).map(|opt| opt.map(|wrap| wrap.0))
}

pub fn tuple_of_cow<'de, D>(deserializer: D) -> Result<(Cow<'de, str>, Cow<'de, str>), D::Error>
where
D: Deserializer<'de>,
(CowWrap<'de>, CowWrap<'de>): Deserialize<'de>,
{
<(CowWrap<'de>, CowWrap<'de>)>::deserialize(deserializer).map(|x| (x.0 .0, x.1 .0))
}

#[test]
fn test_option() {
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
Expand All @@ -38,6 +46,20 @@ fn test_option() {
assert!(matches!(data_new.0, Some(Cow::Borrowed(_))));
}

#[test]
fn test_tuple() {
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
struct Demo<'s>(
#[serde(borrow, deserialize_with = "tuple_of_cow")] (Cow<'s, str>, Cow<'s, str>),
);

let data_orig = Demo(("Hello world".into(), "Hello earth".into()));
let json = serde_json::to_string(&data_orig).expect("serialize");
let data_new = serde_json::from_str::<Demo>(&json).expect("deserialize");
assert_eq!(data_orig, data_new);
assert!(matches!(data_new.0, (Cow::Borrowed(_), Cow::Borrowed(_))));
}

#[test]
fn test_array() {
#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
Expand Down

0 comments on commit df232db

Please sign in to comment.