-
Notifications
You must be signed in to change notification settings - Fork 223
Add icu_provider_adapter::delegate module with helper macro #6853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+44
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current macro implementation is very restrictive as it only allows delegating to a direct field of To make the macro more flexible and support nested field access, you can change
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#[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"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a very small implementation which I'm not sure is worth a macro that has to be special cased for different providers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ambivalent on this. I think it's fine, but I'm not strongly in favor of adding such a macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it less about the macro and more about blessing this pattern as one we want to encourage, with a docs page, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so just write a docs page? the macro seems brittle and learning how to use the macro is more effort than writing the redirecting impl