icu_provider

Macro impl_dynamic_data_provider

Source
macro_rules! impl_dynamic_data_provider {
    ($provider:ty, $arms:tt, $one:path, $($rest:path),+) => { ... };
    ($provider:ty, { $($ident:ident = $key:path => $struct_m:ty),+, $(_ => $struct_d:ty,)?}, $dyn_m:ty) => { ... };
    ($provider:ty, [ $($(#[$cfg:meta])? $struct_m:ty),+, ], $dyn_m:path) => { ... };
}
Expand description

Implements DynamicDataProvider for a marker type S on a type that already implements DynamicDataProvider or DataProvider for one or more M, where M is a concrete type that is convertible to S via UpcastDataPayload.

Use this macro to add support to your data provider for:

§Wrapping DataProvider

If your type implements DataProvider, pass a list of markers as the second argument. This results in a DynamicDataProvider that delegates to a specific marker if the key matches or else returns DataErrorKind::MissingDataKey.

use icu_provider::prelude::*;
use icu_provider::hello_world::*;

// Implement DynamicDataProvider<AnyMarker> on HelloWorldProvider: DataProvider<HelloWorldV1Marker>
icu_provider::impl_dynamic_data_provider!(HelloWorldProvider, [HelloWorldV1Marker,], AnyMarker);

let req = DataRequest {
    locale: &icu_locid::langid!("de").into(),
    metadata: Default::default(),
};

// Successful because the key matches:
HelloWorldProvider.load_data(HelloWorldV1Marker::KEY, req).unwrap();

// MissingDataKey error as the key does not match:
assert_eq!(
    HelloWorldProvider.load_data(icu_provider::data_key!("dummy@1"), req).unwrap_err().kind,
    DataErrorKind::MissingDataKey,
);

§Wrapping DynamicDataProvider

It is also possible to wrap a DynamicDataProvider to create another DynamicDataProvider. To do this, pass a match-like statement for keys as the second argument:

use icu_provider::prelude::*;
use icu_provider::hello_world::*;

// Implement DataProvider<AnyMarker> on HelloWorldProvider: DynamicDataProvider<HelloWorldV1Marker>
icu_provider::impl_dynamic_data_provider!(HelloWorldProvider, {
    // Match HelloWorldV1Marker::KEY and delegate to DynamicDataProvider<HelloWorldV1Marker>.
    HW = HelloWorldV1Marker::KEY => HelloWorldV1Marker,
    // Send the wildcard match also to DynamicDataProvider<HelloWorldV1Marker>.
    _ => HelloWorldV1Marker,
}, AnyMarker);

let req = DataRequest {
    locale: &icu_locid::langid!("de").into(),
    metadata: Default::default(),
};

// Successful because the key matches:
HelloWorldProvider.as_any_provider().load_any(HelloWorldV1Marker::KEY, req).unwrap();

// Because of the wildcard, any key actually works:
HelloWorldProvider.as_any_provider().load_any(icu_provider::data_key!("dummy@1"), req).unwrap();