-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Zibi Braniecki
committed
May 15, 2022
1 parent
5f86e4b
commit 7831678
Showing
4 changed files
with
245 additions
and
285 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | ||
)* | ||
} | ||
} | ||
} | ||
) | ||
} |
Oops, something went wrong.