Skip to content

Commit

Permalink
Fixing Option borrows
Browse files Browse the repository at this point in the history
  • Loading branch information
robertbastian committed Jan 28, 2022
1 parent 405b9fd commit 637f985
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 63 deletions.
17 changes: 17 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion components/datetime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ smallvec = "1.6"
displaydoc = { version = "0.2.3", default-features = false }
either = { version = "1.6.1", default-features = false }
num_enum = { version = "0.5", default_features = false }
serde_with = { version = "1.11.0", default_features = false, optional = true}

[dev-dependencies]
criterion = "0.3"
Expand All @@ -67,7 +68,7 @@ bench = false # This option is required for Benchmark CI
std = ["icu_provider/std", "icu_locid/std", "icu_calendar/std"]
default = ["provider_serde"]
bench = []
provider_serde = ["serde", "litemap/serde_serialize", "smallvec/serde", "litemap/serde", "zerovec/serde", "tinystr/serde"]
provider_serde = ["serde", "litemap/serde_serialize", "smallvec/serde", "litemap/serde", "zerovec/serde", "tinystr/serde", "serde_with"]
provider_transform_internals = ["std"]

[[bench]]
Expand Down
242 changes: 180 additions & 62 deletions components/datetime/src/provider/calendar/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,61 +42,14 @@ pub struct Eras<'data> {
}

macro_rules! symbols {
($name: ident, $expr: ty) => {
pub mod $name {
use super::*;
($name: ident, $symbols: item) => {
pub mod $name {
use super::*;

#[derive(Debug, PartialEq, Clone, Default, ZeroCopyFrom, Yokeable)]
#[cfg_attr(feature="provider_serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SymbolsV1<'data>(#[cfg_attr(feature="provider_serde", serde(borrow))] pub $expr);
#[derive(Debug, PartialEq, Clone, Default, ZeroCopyFrom, Yokeable)]
#[cfg_attr(feature="provider_serde", derive(serde::Serialize, serde::Deserialize))]
$symbols

symbols!();
}
};
($name: ident { $($tokens: tt)* }) => {
symbols!($name { $($tokens)* } -> ());
};
($name: ident { $element: ident: Option<$ty: ty>, $($tokens: tt)+ } -> ($($members:tt)*)) => {
symbols!($name { $($tokens)* } -> (
$($members)*
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub $element: Option<$ty>,
));
};
($name: ident { $element: ident: $ty: ty, $($tokens: tt)+ } -> ($($members:tt)*)) => {
symbols!($name { $($tokens)* } -> (
$($members)*
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub $element: $ty,
));
};
($name: ident { $element: ident: Option<$ty: ty> $(,)? } -> ($($members:tt)*)) => {
symbols!($name { } -> (
$($members)*
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub $element: Option<$ty>,
));
};
($name: ident { $element: ident: $ty: ty $(,)? } -> ($($members:tt)*)) => {
symbols!($name { } -> (
$($members)*
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub $element: $ty,
));
};
($name: ident { } -> ($($members: tt)*)) => {
pub mod $name {
use super::*;

#[derive(Debug, PartialEq, Clone, Default, Yokeable, ZeroCopyFrom)]
#[cfg_attr(feature="provider_serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SymbolsV1<'data> {
$($members)*
}
symbols!();
}
};
() => {
// UTS 35 specifies that `format` widths are mandatory
// except of `short`.
#[derive(Debug, PartialEq, Clone, Default, Yokeable, ZeroCopyFrom)]
Expand Down Expand Up @@ -134,18 +87,183 @@ macro_rules! symbols {
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub stand_alone: Option<StandAloneWidthsV1<'data>>,
}
};
}
}
};
}

symbols!(months, [Cow<'data, str>; 12]);
symbols!(
months,
pub struct SymbolsV1<'data>(
#[cfg_attr(
feature = "provider_serde",
serde(borrow, with = "serde_with::As::<[serde_with::BorrowCow; 12]>")
)]
pub [Cow<'data, str>; 12],
);
);

symbols!(weekdays, [Cow<'data, str>; 7]);
symbols!(
weekdays,
pub struct SymbolsV1<'data>(
#[cfg_attr(
feature = "provider_serde",
serde(borrow, with = "serde_with::As::<[serde_with::BorrowCow; 7]>")
)]
pub [Cow<'data, str>; 7],
);
);

symbols!(
day_periods {
am: Cow<'data, str>,
pm: Cow<'data, str>,
noon: Option<Cow<'data, str>>,
midnight: Option<Cow<'data, str>>,
day_periods,
pub struct SymbolsV1<'data> {
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub am: Cow<'data, str>,
#[cfg_attr(feature = "provider_serde", serde(borrow))]
pub pm: Cow<'data, str>,
#[cfg_attr(
feature = "provider_serde",
serde(borrow, with = "serde_with::As::<Option<serde_with::BorrowCow>>")
)]
pub noon: Option<Cow<'data, str>>,
#[cfg_attr(
feature = "provider_serde",
serde(borrow, with = "serde_with::As::<Option<serde_with::BorrowCow>>")
)]
pub midnight: Option<Cow<'data, str>>,
}
);

#[cfg(all(test, feature = "provider_serde"))]
mod test {
use super::*;

fn serialize() -> Vec<u8> {
let months = months::SymbolsV1([
Cow::Owned("January".to_string()),
Cow::Owned("February".to_string()),
Cow::Owned("March".to_string()),
Cow::Owned("April".to_string()),
Cow::Owned("May".to_string()),
Cow::Owned("June".to_string()),
Cow::Owned("July".to_string()),
Cow::Owned("August".to_string()),
Cow::Owned("September".to_string()),
Cow::Owned("October".to_string()),
Cow::Owned("November".to_string()),
Cow::Owned("December".to_string()),
]);

let weekdays = weekdays::SymbolsV1([
Cow::Owned("Monday".to_string()),
Cow::Owned("Tuesday".to_string()),
Cow::Owned("Wednesday".to_string()),
Cow::Owned("Thursday".to_string()),
Cow::Owned("Friday".to_string()),
Cow::Owned("Saturday".to_string()),
Cow::Owned("Sunday".to_string()),
]);

let day_periods = day_periods::SymbolsV1 {
am: Cow::Owned("am".to_string()),
pm: Cow::Owned("pm".to_string()),
noon: Some(Cow::Owned("noon".to_string())),
midnight: None,
};

bincode::serialize(&DateSymbolsV1 {
months: months::ContextsV1 {
format: months::FormatWidthsV1 {
abbreviated: months.clone(),
narrow: months.clone(),
short: Some(months.clone()),
wide: months.clone(),
},
stand_alone: Some(months::StandAloneWidthsV1 {
abbreviated: Some(months.clone()),
narrow: Some(months.clone()),
short: Some(months.clone()),
wide: Some(months.clone()),
}),
},
weekdays: weekdays::ContextsV1 {
format: weekdays::FormatWidthsV1 {
abbreviated: weekdays.clone(),
narrow: weekdays.clone(),
short: Some(weekdays.clone()),
wide: weekdays.clone(),
},
stand_alone: Some(weekdays::StandAloneWidthsV1 {
abbreviated: Some(weekdays.clone()),
narrow: Some(weekdays.clone()),
short: Some(weekdays.clone()),
wide: Some(weekdays.clone()),
}),
},
day_periods: day_periods::ContextsV1 {
format: day_periods::FormatWidthsV1 {
abbreviated: day_periods.clone(),
narrow: day_periods.clone(),
short: Some(day_periods.clone()),
wide: day_periods.clone(),
},
stand_alone: Some(day_periods::StandAloneWidthsV1 {
abbreviated: Some(day_periods.clone()),
narrow: Some(day_periods.clone()),
short: Some(day_periods.clone()),
wide: Some(day_periods.clone()),
}),
},
eras: Eras {
names: ZeroMap::new(),
abbr: ZeroMap::new(),
narrow: ZeroMap::new(),
},
})
.unwrap()
}

#[test]
fn months_borrows() {
let bytes = serialize();
let de = bincode::deserialize::<DateSymbolsV1>(&bytes).unwrap();

assert!(matches!(de.months.format.narrow.0[2], Cow::Borrowed(_)));
assert!(matches!(
de.months.format.short.as_ref().unwrap().0[11],
Cow::Borrowed(_)
));
}

#[test]
fn weekdays_borrows() {
let bytes = serialize();
let de = bincode::deserialize::<DateSymbolsV1>(&bytes).unwrap();

assert!(matches!(de.weekdays.format.narrow.0[2], Cow::Borrowed(_)));
assert!(matches!(
de.weekdays.format.short.as_ref().unwrap().0[4],
Cow::Borrowed(_)
));
}

#[test]
fn day_periods_borrows() {
let bytes = serialize();
let de = bincode::deserialize::<DateSymbolsV1>(&bytes).unwrap();

assert!(matches!(
de.day_periods.format.narrow.noon,
Some(Cow::Borrowed(_))
));
assert!(matches!(
de.day_periods.format.short.as_ref().unwrap().noon,
Some(Cow::Borrowed(_))
));

assert!(matches!(de.day_periods.format.narrow.am, Cow::Borrowed(_)));
assert!(matches!(
de.day_periods.format.short.as_ref().unwrap().am,
Cow::Borrowed(_)
));
}
}

0 comments on commit 637f985

Please sign in to comment.