Skip to content

Commit

Permalink
Clean up timezone docs and Windows mapper API (#5735)
Browse files Browse the repository at this point in the history
Based on #5730
  • Loading branch information
robertbastian authored Oct 28, 2024
1 parent aee3cd6 commit 161bb79
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 83 deletions.
11 changes: 5 additions & 6 deletions components/timezone/README.md

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

11 changes: 5 additions & 6 deletions components/timezone/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! # Fields
//!
//! In ICU4X, a [formattable time zone](TimeZoneInfo) consists of four different fields:
//! In ICU4X, a [formattable time zone](TimeZoneInfo) consists of up to four different fields:
//!
//! 1. The time zone ID
//! 2. The offset from UTC
Expand Down Expand Up @@ -58,11 +58,10 @@
//! use tinystr::{tinystr, TinyAsciiStr};
//!
//! // Create a time zone for America/Chicago at UTC-6:
//! let mut time_zone = TimeZoneInfo {
//! time_zone_id: TimeZoneIdMapper::new().iana_to_bcp47("America/Chicago"),
//! offset: Some("-0600".parse().unwrap()),
//! ..TimeZoneInfo::unknown()
//! };
//! let mut time_zone = TimeZoneInfo::from_id_and_offset(
//! TimeZoneIdMapper::new().iana_to_bcp47("America/Chicago"),
//! "-0600".parse().unwrap(),
//! );
//!
//! // Alternatively, set it directly from the BCP-47 ID
//! assert_eq!(time_zone.time_zone_id, TimeZoneBcp47Id(tinystr!(8, "uschi")));
Expand Down
100 changes: 30 additions & 70 deletions components/timezone/src/windows_tz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use core::fmt::{self, Write};
use core::fmt::Write;

use icu_provider::{
prelude::icu_locale_core::subtags::Region, DataError, DataPayload, DataProvider,
prelude::icu_locale_core::subtags::{region, Region},
DataError, DataPayload, DataProvider,
};

use crate::{
Expand All @@ -32,7 +33,7 @@ use crate::{
///
/// As such, a [`Region`] may be provided to further specify a desired territory/region when
/// querying a BCP-47 identifier. If no region is provided or the specificity is not required,
/// then the territory will default to the M49 World Code, 001.
/// then the territory will default to the M.49 World Code, `001`.
#[derive(Debug)]
pub struct WindowsTimeZoneMapper {
data: DataPayload<WindowsZonesToBcp47MapV1Marker>,
Expand Down Expand Up @@ -99,104 +100,63 @@ impl WindowsTimeZoneMapperBorrowed<'_> {
}
}

/// Returns the BCP-47 id for a provided windows time zone string with a case sensitive query.
/// Returns the BCP-47 ID for a provided Windows time zone and [`Region`] with a case sensitive query.
///
/// This method will return the canonical identifier for an area as no
/// territory/geo name was provided, so the mapper will use default the default M49 World code ("001").
/// If no region is provided or the specificity is not required,
/// then the territory will default to the M.49 World Code, `001`.
///
/// ```rust
/// use icu_timezone::{WindowsTimeZoneMapperBorrowed, TimeZoneBcp47Id};
/// use icu::timezone::{WindowsTimeZoneMapper, TimeZoneBcp47Id};
/// use icu::locale::subtags::region;
/// use tinystr::tinystr;
///
/// let windows_tz_mapper = WindowsTimeZoneMapperBorrowed::new();
/// let win_tz_mapper = WindowsTimeZoneMapper::new();
///
/// let bcp47_id = windows_tz_mapper.windows_tz_to_bcp47_id("Central Standard Time").unwrap();
/// assert_eq!(bcp47_id, Some(TimeZoneBcp47Id(tinystr!(8, "uschi"))));
/// ```
pub fn windows_tz_to_bcp47_id(
&self,
windows_tz: &str,
) -> Result<Option<TimeZoneBcp47Id>, fmt::Error> {
self.windows_tz_to_bcp47_id_with_region(windows_tz, None)
}

/// Returns the IANA identifier(s) for a provided windows zone bytes and an
/// optional geo_name bytes representing a [`Region`]. If not provided,
/// geo_name will be set to the default of "001", the M49 world code.
///
/// If a `Region` is provided, then the returned is not guaranteed to
/// be a single identifier. The value may be a space delimited list of IANA
/// identifiers for the designated region.
///
/// ```rust
/// use icu_timezone::{WindowsTimeZoneMapperBorrowed, TimeZoneBcp47Id};
/// use icu_provider::prelude::icu_locale_core::subtags::Region;
/// use tinystr::tinystr;
///
/// let win_tz_mapper = WindowsTimeZoneMapperBorrowed::new();
///
/// let region = None;
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id_with_region("Central Standard Time", region).unwrap();
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id("Central Standard Time", None);
/// assert_eq!(bcp47_id, Some(TimeZoneBcp47Id(tinystr!(8, "uschi"))));
///
/// let region = Some(Region::try_from_str("US").unwrap());
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id_with_region("Central Standard Time", region).unwrap();
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id("Central Standard Time", Some(region!("US")));
/// assert_eq!(bcp47_id, Some(TimeZoneBcp47Id(tinystr!(8, "uschi"))));
///
/// let region = Some(Region::try_from_str("CA").unwrap());
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id_with_region("Central Standard Time", region).unwrap();
/// let bcp47_id = win_tz_mapper.windows_tz_to_bcp47_id("Central Standard Time", Some(region!("CA")));
/// assert_eq!(bcp47_id, Some(TimeZoneBcp47Id(tinystr!(8, "cawnp"))));
/// ```
pub fn windows_tz_to_bcp47_id_with_region(
&self,
windows_tz: &str,
region: Option<Region>,
) -> Result<Option<TimeZoneBcp47Id>, fmt::Error> {
Ok(self
.windows_tz_lookup(windows_tz, region)?
.and_then(|index| self.data.bcp47_ids.get(index)))
}

/// Look up the index of a windows time zone with a provided windows time zone and region.
fn windows_tz_lookup(
pub fn windows_tz_to_bcp47_id(
&self,
windows_tz: &str,
region: Option<Region>,
) -> Result<Option<usize>, fmt::Error> {
) -> Option<TimeZoneBcp47Id> {
let mut cursor = self.data.map.cursor();
cursor.write_str(windows_tz)?;
// Returns None if input is non-ASCII
cursor.write_str(windows_tz).ok()?;
cursor.step(b'/');
match region {
Some(region) => cursor.write_str(region.as_str())?,
None => cursor.write_str("001")?,
};
Ok(cursor.take_value())
cursor
.write_str(region.unwrap_or(region!("001")).as_str())
// region is valid ASCII, but we can do this instead of unwrap
.ok()?;
self.data.bcp47_ids.get(cursor.take_value()?)
}
}

#[cfg(test)]
mod tests {
use super::*;
use tinystr::tinystr;

use crate::TimeZoneBcp47Id;

use super::WindowsTimeZoneMapperBorrowed;

#[test]
fn basic_windows_tz_lookup() {
let win_map = WindowsTimeZoneMapperBorrowed::new();
let win_map = WindowsTimeZoneMapper::new();

let result = win_map
.windows_tz_to_bcp47_id("Central Standard Time")
.unwrap();
let result = win_map.windows_tz_to_bcp47_id("Central Standard Time", None);
assert_eq!(result, Some(TimeZoneBcp47Id(tinystr!(8, "uschi"))));

let result = win_map
.windows_tz_to_bcp47_id("Eastern Standard Time")
.unwrap();
let result = win_map.windows_tz_to_bcp47_id("Eastern Standard Time", None);
assert_eq!(result, Some(TimeZoneBcp47Id(tinystr!(8, "usnyc"))));

let result = win_map.windows_tz_to_bcp47_id("GMT Standard Time").unwrap();
let result = win_map.windows_tz_to_bcp47_id("Eastern Standard Time", Some(region!("CA")));
assert_eq!(result, Some(TimeZoneBcp47Id(tinystr!(8, "cator"))));

let result = win_map.windows_tz_to_bcp47_id("GMT Standard Time", None);
assert_eq!(result, Some(TimeZoneBcp47Id(tinystr!(8, "gblon"))));
}
}
1 change: 0 additions & 1 deletion ffi/capi/tests/missing_apis.txt
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@ icu::timezone::WindowsTimeZoneMapper::new#FnInStruct
icu::timezone::WindowsTimeZoneMapperBorrowed#Struct
icu::timezone::WindowsTimeZoneMapperBorrowed::new#FnInStruct
icu::timezone::WindowsTimeZoneMapperBorrowed::windows_tz_to_bcp47_id#FnInStruct
icu::timezone::WindowsTimeZoneMapperBorrowed::windows_tz_to_bcp47_id_with_region#FnInStruct
icu::timezone::ZoneOffsetCalculator#Struct
icu::timezone::ZoneOffsetCalculator::compute_offsets_from_time_zone#FnInStruct
icu::timezone::ZoneOffsetCalculator::new#FnInStruct
Expand Down

0 comments on commit 161bb79

Please sign in to comment.