Skip to content

Commit

Permalink
Switch to macro
Browse files Browse the repository at this point in the history
  • Loading branch information
Zibi Braniecki committed May 15, 2022
1 parent 5f86e4b commit 7831678
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 285 deletions.
123 changes: 0 additions & 123 deletions utils/preferences/src/dtf.rs

This file was deleted.

79 changes: 2 additions & 77 deletions utils/preferences/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,80 +1,5 @@
mod dtf;
mod preferences;
#[macro_use]
mod macros;

pub use dtf::{DTFPreferencesBag, DateTimeFormat};
pub use preferences::Preferences;

#[cfg(test)]
mod tests {
use super::*;
use icu_datetime::options::preferences::HourCycle;
use icu_locid::{language, locale, Locale};

#[test]
fn it_works() {
{
// Default locale, no prefs
let loc = locale!("en-US");
let dtf = DateTimeFormat::try_new(&loc);
assert_eq!(dtf.format().as_str(), "05/13/2022 3:00pm");
}

{
// Prefs, no locale
let p = DTFPreferencesBag {
hour_cycle: Some(HourCycle::H12),
..Default::default()
};
let dtf = DateTimeFormat::try_new(&p);
assert_eq!(dtf.format().as_str(), "ISO DATE 3:00pm");
}

{
// Prefs and locale
let mut p = DTFPreferencesBag {
hour_cycle: Some(HourCycle::H24),
..Default::default()
};
p.merge_locale(&locale!("fr-CA")).unwrap();

let dtf = DateTimeFormat::try_new(&p);
assert_eq!(dtf.format().as_str(), "13/05/2022 15:00");
}

{
// Prefs and locale, override language
let mut p = DTFPreferencesBag {
language: Some(language!("en")),
..Default::default()
};
p.merge_locale(&locale!("fr-CA")).unwrap();

let dtf = DateTimeFormat::try_new(&p);
assert_eq!(dtf.format().as_str(), "05/13/2022 3:00pm");
}

{
// Prefs and locale, override language and set hour_cycle
let mut p = DTFPreferencesBag {
language: Some(language!("en")),
hour_cycle: Some(HourCycle::H24),
..Default::default()
};
p.merge_locale(&locale!("fr-CA")).unwrap();

let dtf = DateTimeFormat::try_new(&p);
assert_eq!(dtf.format().as_str(), "05/13/2022 15:00");
}

{
let mut p = DTFPreferencesBag {
..Default::default()
};
let loc: Locale = "fr-CA-u-hc-h12".parse().unwrap();
p.merge_locale(&loc).unwrap();

let dtf = DateTimeFormat::try_new(&p);
assert_eq!(dtf.format().as_str(), "13/05/2022 3:00pm");
}
}
}
136 changes: 136 additions & 0 deletions utils/preferences/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#[macro_export]
macro_rules! preferences {
($trait:ident, $name:ident, $resolved_name:ident, {$($key:ident => $pref:ty, $resolved:ty, $ue:expr),*}) => (
pub trait $trait: Preferences {
$(
fn $key(&self) -> $pref {
None
}
)*
}

#[derive(Default)]
#[non_exhaustive]
pub struct $name {
pub lid: Option<icu_locid::LanguageIdentifier>,
$(
pub $key: $pref,
)*
}

pub struct $resolved_name {
pub lid: icu_locid::LanguageIdentifier,

$(
$key: $resolved,
)*
}

impl Preferences for $name {
fn language(&self) -> &icu_locid::subtags::Language {
self.lid
.as_ref()
.map(|lid| &lid.language)
.unwrap_or(&icu_locid::subtags::Language::UND)
}

fn script(&self) -> Option<&icu_locid::subtags::Script> {
self.lid.as_ref().and_then(|lid| lid.script.as_ref())
}

fn region(&self) -> Option<&icu_locid::subtags::Region> {
self.lid.as_ref().and_then(|lid| lid.region.as_ref())
}
}

impl $trait for Locale {
$(
fn $key(&self) -> $pref {
let ue = $ue.unwrap();
if let Some(value) = self
.extensions
.unicode
.keywords
.get(&ue)
{
//XXX: This is fallible!
if let Ok(v) = TryInto::try_into(value) {
return Some(v);
}
}
return None;
}
)*
}

impl $trait for $name {
$(
fn $key(&self) -> $pref {
self.$key
}
)*
}

impl $name {
#[allow(clippy::result_unit_err)]
pub fn merge_locale(&mut self, locale: &Locale) -> Result<(), ()> {
if let Some(lid) = &mut self.lid {
if lid.language.is_empty() && !locale.id.language.is_empty() {
lid.language = locale.id.language;
};
if lid.script.is_none() && locale.id.script.is_some() {
lid.script = locale.id.script;
}
if lid.region.is_none() && locale.id.region.is_some() {
lid.region = locale.id.region;
}
} else {
self.lid = Some(locale.id.clone());
}

$(
let ue = $ue.unwrap();
if self.$key.is_none() {
if let Some(value) = locale
.extensions
.unicode
.keywords
.get(&ue)
{
self.$key = Some(TryInto::try_into(value)?);
}
}
)*
Ok(())
}
}

impl $resolved_name {
fn resolve(&self, prefs: &impl $trait) -> Self {
let mut language = prefs.language();
if language.is_empty() {
language = &self.lid.language;
}
let mut script = prefs.script();
if script.is_none() {
script = self.lid.script.as_ref();
}
let mut region = prefs.region();
if region.is_none() {
region = self.lid.region.as_ref();
}
Self {
lid: icu_locid::LanguageIdentifier {
language: *language,
script: script.copied(),
region: region.copied(),
variants: icu_locid::subtags::Variants::new()
},
$(
$key: prefs.$key().unwrap_or(self.$key),
)*
}
}
}
)
}
Loading

0 comments on commit 7831678

Please sign in to comment.