Skip to content

Commit

Permalink
Add NeverMarker (#4674)
Browse files Browse the repository at this point in the history
Fixes #4186
  • Loading branch information
sffc committed Mar 12, 2024
1 parent 183c70c commit f832e5e
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 1 deletion.
1 change: 1 addition & 0 deletions provider/baked/calendar/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/casemap/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/collator/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/datetime/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/decimal/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/experimental/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/list/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/locid_transform/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/normalizer/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/plurals/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/properties/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/segmenter/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/baked/timezone/data/macros.rs

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

1 change: 1 addition & 0 deletions provider/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ pub use crate::buf::BufferMarker;
pub use crate::buf::BufferProvider;
pub use crate::marker::DataMarker;
pub use crate::marker::KeyedDataMarker;
pub use crate::marker::NeverMarker;
#[cfg(feature = "serde")]
pub use crate::serde::AsDeserializingBufferProvider;

Expand Down
108 changes: 107 additions & 1 deletion provider/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

//! Marker types and traits for DataProvider.

use crate::key::DataKey;
use core::marker::PhantomData;

use crate::{data_key, key::DataKey};
use yoke::Yokeable;

/// Trait marker for data structs. All types delivered by the data provider must be associated with
Expand Down Expand Up @@ -83,3 +85,107 @@ pub trait KeyedDataMarker: DataMarker {
/// The single [`DataKey`] associated with this marker.
const KEY: DataKey;
}

/// A [`DataMarker`] that never returns data.
///
/// All types that have non-blanket impls of `DataProvider<M>` are expected to explicitly
/// implement `DataProvider<NeverMarker<Y>>`, returning [`DataErrorKind::MissingDataKey`].
/// See [`impl_data_provider_never_marker!`].
///
/// [`DataErrorKind::MissingDataKey`]: crate::DataErrorKind::MissingDataKey
/// [`impl_data_provider_never_marker!`]: crate::impl_data_provider_never_marker
///
/// # Examples
///
/// ```
/// use icu_locid::locale;
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use icu_provider::NeverMarker;
///
/// let buffer_provider = HelloWorldProvider.into_json_provider();
///
/// let result = DataProvider::<NeverMarker<HelloWorldV1<'static>>>::load(
/// &buffer_provider.as_deserializing(),
/// DataRequest {
/// locale: &locale!("en").into(),
/// metadata: Default::default(),
/// },
/// );
///
/// assert!(matches!(
/// result,
/// Err(DataError {
/// kind: DataErrorKind::MissingDataKey,
/// ..
/// })
/// ));
/// ```
#[derive(Debug, Copy, Clone)]
pub struct NeverMarker<Y>(PhantomData<Y>);

impl<Y> DataMarker for NeverMarker<Y>
where
for<'a> Y: Yokeable<'a>,
{
type Yokeable = Y;
}

impl<Y> KeyedDataMarker for NeverMarker<Y>
where
for<'a> Y: Yokeable<'a>,
{
const KEY: DataKey = data_key!("_never@1");
}

/// Implements `DataProvider<NeverMarker<Y>>` on a struct.
///
/// For more information, see [`NeverMarker`].
///
/// # Examples
///
/// ```
/// use icu_locid::locale;
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use icu_provider::NeverMarker;
///
/// struct MyProvider;
///
/// icu_provider::impl_data_provider_never_marker!(MyProvider);
///
/// let result = DataProvider::<NeverMarker<HelloWorldV1<'static>>>::load(
/// &MyProvider,
/// DataRequest {
/// locale: &locale!("und").into(),
/// metadata: Default::default(),
/// },
/// );
///
/// assert!(matches!(
/// result,
/// Err(DataError {
/// kind: DataErrorKind::MissingDataKey,
/// ..
/// })
/// ));
/// ```
#[macro_export]
macro_rules! impl_data_provider_never_marker {
($ty:path) => {
impl<Y> $crate::DataProvider<$crate::NeverMarker<Y>> for $ty
where
for<'a> Y: $crate::yoke::Yokeable<'a>,
{
fn load(
&self,
req: $crate::DataRequest,
) -> Result<$crate::DataResponse<$crate::NeverMarker<Y>>, $crate::DataError> {
Err($crate::DataErrorKind::MissingDataKey.with_req(
<$crate::NeverMarker<Y> as $crate::KeyedDataMarker>::KEY,
req,
))
}
}
};
}
1 change: 1 addition & 0 deletions provider/datagen/src/baked_exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ impl BakedExporter {
#[allow(dead_code)]
pub const MUST_USE_MAKE_PROVIDER_MACRO: () = ();
}
icu_provider::impl_data_provider_never_marker!($name);
};
}
#[doc(inline)]
Expand Down
1 change: 1 addition & 0 deletions provider/datagen/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct DatagenProvider {
}

crate::registry::make_exportable_provider!(DatagenProvider);
icu_provider::impl_data_provider_never_marker!(DatagenProvider);

impl DatagenProvider {
/// The latest CLDR JSON tag that has been verified to work with this version of `icu_datagen`.
Expand Down
1 change: 1 addition & 0 deletions provider/datagen/tests/data/baked/macros.rs

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

0 comments on commit f832e5e

Please sign in to comment.