Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions components/icu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ required-features = ["compiled_data"]
name = "code_line_diff"
required-features = ["serde"]

[[example]]
name = "coll_mis"
required-features = ["serde"]

[[example]]
name = "and_list"

Expand Down
104 changes: 104 additions & 0 deletions components/icu/examples/coll_mis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

#![no_main] // https://github.com/unicode-org/icu4x/issues/395
icu_benchmark_macros::instrument!();

use icu_benchmark_macros::println;

use icu::collator::Collator;
use icu::locale::locale;
use icu_collator::options::CollatorOptions;
use icu_collator::provider::*;
use icu_collator::CollatorPreferences;
use icu_normalizer::provider::*;
use icu_provider_adapters::fork::ForkByMarkerProvider;
use icu_provider_blob::BlobDataProvider;

fn main() {
let mis_blob = std::fs::read("mis_collation.postcard").unwrap();
let root_blob = std::fs::read("root_collation.postcard").unwrap();

let blob_provider = ForkByMarkerProvider::new(
BlobDataProvider::try_new_from_blob(mis_blob.clone().into()).unwrap(),
BlobDataProvider::try_new_from_blob(root_blob.into()).unwrap(),
);

struct MyProvider {
blob: BlobDataProvider,
collator: icu::collator::provider::Baked,
normalizer: icu::normalizer::provider::Baked,
}

icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationMetadataV1,
&self.blob.as_deserializing()
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationTailoringV1,
&self.blob.as_deserializing()
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationDiacriticsV1,
&self.collator
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationJamoV1,
&self.collator
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationReorderingV1,
&self.collator
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationRootV1,
&self.collator
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
CollationSpecialPrimariesV1,
&self.collator
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
NormalizerNfdDataV1,
&self.normalizer
);
icu_provider_adapters::delegate::data_provider_to_field!(
MyProvider,
NormalizerNfdTablesV1,
&self.normalizer
);

let prefs = CollatorPreferences::from(locale!("mis"));
let options = CollatorOptions::default();

let blob_or_baked_provider = MyProvider {
blob: BlobDataProvider::try_new_from_blob(mis_blob.into()).unwrap(),
collator: icu::collator::provider::Baked,
normalizer: icu::normalizer::provider::Baked,
};

let default_collator = Collator::try_new(prefs, options).unwrap();
let custom_blob_collator =
Collator::try_new_with_buffer_provider(&blob_provider, prefs, options).unwrap();
let custom_baked_collator =
Collator::try_new_unstable(&blob_or_baked_provider, prefs, options).unwrap();

println!("Default: {:?}", default_collator.compare("ı", "I"));
println!(
"Custom All Blob: {:?}",
custom_blob_collator.as_borrowed().compare("ı", "I")
);
println!(
"Custom Blob Baked Hybrid: {:?}",
custom_baked_collator.as_borrowed().compare("ı", "I")
);
}
Binary file added components/icu/mis_collation.postcard
Binary file not shown.
Binary file added components/icu/root_collation.postcard
Binary file not shown.
97 changes: 97 additions & 0 deletions provider/adapters/src/delegate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

//! Macros for delegating impls to inner data providers.

/// Delegate an impl of `DataProvider<M>` to a field of a struct.
///
/// # Examples
///
/// ```
/// use icu_provider::hello_world::*;
/// use icu_locale::locale;
///
/// struct Wrap(HelloWorldProvider);
///
/// // Delegate `DataProvider<HelloWorldV1>` to the field `self.0`
/// icu_provider_adapters::delegate::data_provider_to_field!(Wrap, HelloWorldV1, &self.0);
///
/// // Test that it works
/// let wrap = Wrap(HelloWorldProvider::default());
/// HelloWorldFormatter::try_new_unstable(&wrap, locale!("de").into()).unwrap();
/// ```
///
/// Also works if the field is a [`BufferProvider`]:
///
/// ```
/// use icu_provider::hello_world::*;
/// use icu_locale::locale;
///
/// struct Wrap(HelloWorldJsonProvider);
///
/// // Delegate `DataProvider<HelloWorldV1>` to the field `self.0`, calling `as_deserializing()` on the field
/// icu_provider_adapters::delegate::data_provider_to_field!(Wrap, HelloWorldV1, &self.0.as_deserializing());
///
/// // Test that it works
/// let wrap = Wrap(HelloWorldProvider::default().into_json_provider());
/// HelloWorldFormatter::try_new_unstable(&wrap, locale!("de").into()).unwrap();
/// ```
///
/// [`BufferProvider`]: icu_provider::prelude::BufferProvider
#[doc(hidden)] // macro
#[macro_export]
macro_rules! __data_provider_to_field {
($provider:path, $marker:path, &self.$field:tt.as_deserializing()) => {
impl $crate::icu_provider::DataProvider<$marker> for $provider {
fn load(&self, req: $crate::icu_provider::DataRequest) -> Result<$crate::icu_provider::DataResponse<$marker>, $crate::icu_provider::DataError> {
let provider = $crate::icu_provider::prelude::AsDeserializingBufferProvider::as_deserializing(&self.$field);
$crate::icu_provider::DataProvider::<$marker>::load(&provider, req)
}
}
};
($provider:path, $marker:path, &self.$field:tt) => {
impl $crate::icu_provider::DataProvider<$marker> for $provider {
fn load(&self, req: $crate::icu_provider::DataRequest) -> Result<$crate::icu_provider::DataResponse<$marker>, $crate::icu_provider::DataError> {
$crate::icu_provider::DataProvider::<$marker>::load(&self.$field, req)
}
}
};
}

#[doc(inline)]
pub use __data_provider_to_field as data_provider_to_field;

#[cfg(test)]
mod tests {
use icu_locale::locale;
use icu_provider::hello_world::{
HelloWorldFormatter, HelloWorldJsonProvider, HelloWorldProvider, HelloWorldV1,
};

use super::*;

#[test]
fn test_delegate() {
struct Wrap(HelloWorldProvider);
data_provider_to_field!(Wrap, HelloWorldV1, &self.0);

let hello1 = HelloWorldProvider::default();
let wrap = Wrap(hello1);

let formatter = HelloWorldFormatter::try_new_unstable(&wrap, locale!("de").into()).unwrap();
assert_eq!(formatter.format_to_string(), "Hallo Welt");
}

#[test]
fn test_delegate_to_buffer() {
struct Wrap(HelloWorldJsonProvider);
data_provider_to_field!(Wrap, HelloWorldV1, &self.0.as_deserializing());

let hello1 = HelloWorldProvider::default().into_json_provider();
let wrap = Wrap(hello1);

let formatter = HelloWorldFormatter::try_new_unstable(&wrap, locale!("de").into()).unwrap();
assert_eq!(formatter.format_to_string(), "Hallo Welt");
}
}
4 changes: 4 additions & 0 deletions provider/adapters/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@

extern crate alloc;

pub mod delegate;
pub mod either;
pub mod empty;
pub mod fallback;
pub mod filter;
pub mod fixed;
pub mod fork;

#[doc(hidden)] // internal for macros
pub use icu_provider;
Loading