Skip to content

Commit

Permalink
MultiForkByKeyProvider for all datagen
Browse files Browse the repository at this point in the history
  • Loading branch information
robertbastian committed Feb 16, 2022
1 parent 68e051a commit 0c24b51
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 350 deletions.
17 changes: 0 additions & 17 deletions provider/cldr/src/cldr_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ pub trait CldrPaths: std::fmt::Debug {
// more calendars here
vec
}

/// Path to uprops TOML data, which is required by some CLDR transformers
fn uprops(&self) -> Result<PathBuf, Error>;
}

/// An implementation of [`CldrPaths`] for multiple separate local CLDR JSON directories per
Expand Down Expand Up @@ -112,12 +109,6 @@ impl CldrPaths for CldrPathsLocal {
fn cldr_misc(&self) -> Result<PathBuf, Error> {
self.cldr_misc.clone().map_err(|e| e.into())
}
fn uprops(&self) -> Result<PathBuf, Error> {
Err(Error::Custom(
"This implementation does not know about uprops".to_owned(),
None,
))
}
}

impl Default for CldrPathsLocal {
Expand Down Expand Up @@ -162,8 +153,6 @@ pub struct CldrPathsAllInOne {
pub cldr_json_root: PathBuf,
/// CLDR JSON directory suffix: probably either "modern" or "full"
pub locale_subset: String,
/// Path to uprops TOML root directory. Required by some CLDR transformers
pub uprops_root: Option<PathBuf>,
}

impl CldrPaths for CldrPathsAllInOne {
Expand Down Expand Up @@ -200,18 +189,12 @@ impl CldrPaths for CldrPathsAllInOne {
.clone()
.join(format!("cldr-misc-{}", self.locale_subset)))
}
fn uprops(&self) -> Result<PathBuf, Error> {
self.uprops_root
.clone()
.ok_or_else(|| Error::Custom("The uprops root has not been set".to_owned(), None))
}
}

#[cfg(test)]
pub(crate) fn for_test() -> CldrPathsAllInOne {
CldrPathsAllInOne {
cldr_json_root: icu_testdata::paths::cldr_json_root(),
locale_subset: "full".to_string(),
uprops_root: Some(icu_testdata::paths::uprops_toml_root()),
}
}
3 changes: 1 addition & 2 deletions provider/cldr/src/download/cldr_allinone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,12 @@ impl CldrAllInOneDownloader {
})
}

pub fn download(self, uprops_root: Option<PathBuf>) -> Result<CldrPathsAllInOne, Error> {
pub fn download(self) -> Result<CldrPathsAllInOne, Error> {
// TODO(#297): Implement this async.
let downloaded = io_util::download_and_unzip(&self.url, &self.cache_dir)?;
Ok(CldrPathsAllInOne {
cldr_json_root: downloaded,
locale_subset: self.locale_subset,
uprops_root,
})
}
}
14 changes: 6 additions & 8 deletions provider/cldr/src/transform/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,20 @@ use icu_list::provider::*;
use icu_locid_macros::langid;
use icu_provider::iter::IterableResourceProvider;
use icu_provider::prelude::*;
use std::convert::TryFrom;
use std::path::PathBuf;

/// A data provider reading from CLDR JSON list rule files.
#[derive(Debug)]
pub struct ListProvider {
cldr_misc: PathBuf,
uprops_path: PathBuf,
uprops_root: PathBuf,
}

impl TryFrom<&dyn CldrPaths> for ListProvider {
type Error = Error;
fn try_from(cldr_paths: &dyn CldrPaths) -> Result<Self, Self::Error> {
impl ListProvider {
pub fn try_from(cldr_paths: &dyn CldrPaths, uprops_root: PathBuf) -> Result<Self, Error> {
Ok(Self {
cldr_misc: cldr_paths.cldr_misc()?,
uprops_path: cldr_paths.uprops()?,
uprops_root,
})
}
}
Expand Down Expand Up @@ -116,8 +114,8 @@ impl<M: ResourceMarker<Yokeable = ListFormatterPatternsV1<'static>>> ResourcePro
&format!(
"[^{}]",
icu_properties::sets::get_for_script(
&icu_provider_uprops::PropertiesDataProvider::try_new(
&self.uprops_path
&icu_provider_uprops::EnumeratedPropertyUnicodeSetDataProvider::try_new(
&self.uprops_root
)
.map_err(|e| DataError::custom("Properties data provider error")
.with_display_context(&e))?,
Expand Down
4 changes: 3 additions & 1 deletion provider/cldr/src/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ use icu_provider::iter::IterableDynProvider;
use icu_provider::prelude::*;
use icu_provider::serde::SerializeMarker;
use std::convert::TryFrom;
use std::path::PathBuf;

pub struct CldrJsonDataProvider;

impl CldrJsonDataProvider {
pub fn try_new(
cldr_paths: &dyn CldrPaths,
uprops_root: PathBuf,
) -> Result<MultiForkByKeyProvider<Box<dyn IterableDynProvider<SerializeMarker>>>, Error> {
Ok(MultiForkByKeyProvider {
providers: vec![
Expand Down Expand Up @@ -55,7 +57,7 @@ impl CldrJsonDataProvider {
Box::new(plurals::PluralsProvider::try_from(cldr_paths)?),
Box::new(time_zones::TimeZonesProvider::try_from(cldr_paths)?),
#[cfg(feature = "icu_list")]
Box::new(list::ListProvider::try_from(cldr_paths)?),
Box::new(list::ListProvider::try_from(cldr_paths, uprops_root)?),
],
})
}
Expand Down
18 changes: 7 additions & 11 deletions provider/core/src/dynutil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ where
/// [`SerializeMarker`]: (crate::serde::SerializeMarker)
#[macro_export]
macro_rules! impl_dyn_provider {
($provider:ty, { $($pat:pat => $struct_m:ty),+, }, ANY) => {
($provider:ty, { $($pat:pat $(if $guard:expr)? => $struct_m:ty),+, }, ANY) => {
$crate::impl_dyn_provider!(
$provider,
{ $($pat => $struct_m),+, },
{ $($pat $(if $guard)? => $struct_m),+, },
$crate::any::AnyMarker
);
};
Expand All @@ -173,11 +173,11 @@ macro_rules! impl_dyn_provider {
$crate::any::AnyMarker
);
};
($provider:ty, { $($pat:pat => $struct_m:ty),+, }, SERDE_SE) => {
($provider:ty, { $($pat:pat $(if $guard:expr)? => $struct_m:ty),+, }, SERDE_SE) => {
// If this fails to compile, enable the "serialize" feature on this crate.
$crate::impl_dyn_provider!(
$provider,
{ $($pat => $struct_m),+, },
{ $($pat $(if $guard)? => $struct_m),+, },
$crate::serde::SerializeMarker
);
};
Expand All @@ -189,7 +189,7 @@ macro_rules! impl_dyn_provider {
$crate::serde::SerializeMarker
);
};
($provider:ty, { $($pat:pat => $struct_m:ty),+, }, $dyn_m:path) => {
($provider:ty, { $($pat:pat $(if $guard:expr)? => $struct_m:ty),+, }, $dyn_m:path) => {
impl $crate::DynProvider<$dyn_m> for $provider
{
fn load_payload(
Expand All @@ -202,7 +202,7 @@ macro_rules! impl_dyn_provider {
> {
match key {
$(
$pat => {
$pat $(if $guard)? => {
let result: $crate::DataResponse<$struct_m> =
$crate::DynProvider::<$struct_m>::load_payload(self, key, req)?;
Ok(DataResponse {
Expand All @@ -213,8 +213,6 @@ macro_rules! impl_dyn_provider {
})
}
)+,
// Don't complain if the call site has its own wildcard match
#[allow(unreachable_patterns)]
_ => Err($crate::DataErrorKind::MissingResourceKey.with_req(key, req))
}
}
Expand All @@ -224,12 +222,10 @@ macro_rules! impl_dyn_provider {
fn supported_options_for_key(&self, key: &$crate::ResourceKey) -> Result<Box<dyn Iterator<Item = $crate::ResourceOptions> + '_>, $crate::DataError> {
match *key {
$(
$pat => {
$pat $(if $guard)? => {
$crate::iter::IterableDynProvider::<$struct_m>::supported_options_for_key(self, key)
}
)+,
// Don't complain if the call site has its own wildcard match
#[allow(unreachable_patterns)]
_ => Err($crate::DataErrorKind::MissingResourceKey.with_key(*key))
}
}
Expand Down
2 changes: 1 addition & 1 deletion provider/uprops/src/bin_uniset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl DynProvider<UnicodePropertyV1Marker> for BinaryPropertyUnicodeSetDataProvid
}

icu_provider::impl_dyn_provider!(BinaryPropertyUnicodeSetDataProvider, {
_ => UnicodePropertyV1Marker,
_k if _k.get_path().starts_with("props/") => UnicodePropertyV1Marker,
}, SERDE_SE);

impl IterableDynProvider<UnicodePropertyV1Marker> for BinaryPropertyUnicodeSetDataProvider {
Expand Down
2 changes: 1 addition & 1 deletion provider/uprops/src/enum_uniset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl DynProvider<UnicodePropertyV1Marker> for EnumeratedPropertyUnicodeSetDataPr
}

icu_provider::impl_dyn_provider!(EnumeratedPropertyUnicodeSetDataProvider, {
_ => UnicodePropertyV1Marker,
_k if _k.get_path().starts_with("props/") && _k.get_path().contains('=') => UnicodePropertyV1Marker,
}, SERDE_SE);

impl IterableDynProvider<UnicodePropertyV1Marker> for EnumeratedPropertyUnicodeSetDataProvider {
Expand Down
5 changes: 3 additions & 2 deletions provider/uprops/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod script;
mod uprops_helpers;
mod uprops_serde;

pub use enum_codepointtrie::EnumeratedPropertyCodePointTrieProvider;
pub use provider::PropertiesDataProvider;
pub use script::ScriptWithExtensionsPropertyProvider;

// Required by icu_provider_cldr::transform::list
pub use enum_uniset::EnumeratedPropertyUnicodeSetDataProvider;
69 changes: 25 additions & 44 deletions provider/uprops/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,38 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use crate::bin_uniset::BinaryPropertyUnicodeSetDataProvider;
use crate::enum_uniset::EnumeratedPropertyUnicodeSetDataProvider;
use crate::uprops_helpers::get_last_component_no_version;
use icu_properties::provider::UnicodePropertyV1Marker;
use icu_provider::fork::by_key::MultiForkByKeyProvider;
use icu_provider::iter::IterableDynProvider;
use icu_provider::prelude::*;

use icu_provider::serde::SerializeMarker;
use std::path::Path;

/// This data provider returns `UnicodeSet` data inside a `UnicodeProperty`
/// data struct. The source data is in the form of a directory of TOML file(s)
/// of data for the property(-ies) desired, as given by the ICU4C property data
/// exporter tool.
pub struct PropertiesDataProvider {
binary: BinaryPropertyUnicodeSetDataProvider,
enumerated: EnumeratedPropertyUnicodeSetDataProvider,
}

pub struct PropertiesDataProvider;
impl PropertiesDataProvider {
/// Construct a new data provider instance. `root_dir` is the path to the
/// root directory containing the property data TOML files.
pub fn try_new(root_dir: &Path) -> eyre::Result<Self> {
let binary = BinaryPropertyUnicodeSetDataProvider::try_new(root_dir)?;
let enumerated = EnumeratedPropertyUnicodeSetDataProvider::try_new(root_dir)?;
Ok(Self { binary, enumerated })
}
}

impl DynProvider<UnicodePropertyV1Marker> for PropertiesDataProvider {
fn load_payload(
&self,
key: ResourceKey,
req: &DataRequest,
) -> Result<DataResponse<UnicodePropertyV1Marker>, DataError> {
if get_last_component_no_version(&key).contains('=') {
self.enumerated.load_payload(key, req)
} else {
self.binary.load_payload(key, req)
}
}
}

icu_provider::impl_dyn_provider!(PropertiesDataProvider, {
_ => UnicodePropertyV1Marker,
}, SERDE_SE);

impl IterableDynProvider<UnicodePropertyV1Marker> for PropertiesDataProvider {
fn supported_options_for_key(
&self,
_resc_key: &ResourceKey,
) -> Result<Box<dyn Iterator<Item = ResourceOptions>>, DataError> {
Ok(Box::new(core::iter::once(ResourceOptions::default())))
pub fn try_new(
root_dir: &Path,
) -> eyre::Result<MultiForkByKeyProvider<Box<dyn IterableDynProvider<SerializeMarker>>>> {
Ok(MultiForkByKeyProvider {
providers: vec![
Box::new(
crate::enum_codepointtrie::EnumeratedPropertyCodePointTrieProvider::try_new(
root_dir,
)?,
),
Box::new(crate::script::ScriptWithExtensionsPropertyProvider::try_new(root_dir)?),
Box::new(
crate::enum_uniset::EnumeratedPropertyUnicodeSetDataProvider::try_new(
root_dir,
)?,
),
// Has to go last as it matches all props/ keys.
Box::new(
crate::bin_uniset::BinaryPropertyUnicodeSetDataProvider::try_new(root_dir)?,
),
],
})
}
}
Loading

0 comments on commit 0c24b51

Please sign in to comment.