Skip to content

Commit

Permalink
Add missing DryDataProvider implementations (#5951)
Browse files Browse the repository at this point in the history
Makes it a bit easier to work with `&DryDataProvider`,
`&DynamicDryDataProvider` and friends.
  • Loading branch information
jedel1043 authored Jan 7, 2025
1 parent 1814f5f commit ff90048
Showing 1 changed file with 132 additions and 26 deletions.
158 changes: 132 additions & 26 deletions provider/core/src/data_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,6 @@ where
}
}

/// A [`DataProvider`] that can iterate over all supported [`DataIdentifierCow`]s.
///
/// The provider is not allowed to return `Ok` for requests that were not returned by `iter_ids`,
/// and must not fail with a [`DataErrorKind::IdentifierNotFound`] for requests that were returned.
pub trait IterableDataProvider<M: DataMarker>: DataProvider<M> {
/// Returns a set of [`DataIdentifierCow`].
fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow>, DataError>;
}

#[cfg(target_has_atomic = "ptr")]
impl<M, P> DataProvider<M> for alloc::sync::Arc<P>
where
Expand All @@ -87,6 +78,60 @@ pub trait DryDataProvider<M: DataMarker>: DataProvider<M> {
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError>;
}

impl<M, P> DryDataProvider<M> for &P
where
M: DataMarker,
P: DryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
(*self).dry_load(req)
}
}

impl<M, P> DryDataProvider<M> for Box<P>
where
M: DataMarker,
P: DryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load(req)
}
}

impl<M, P> DryDataProvider<M> for alloc::rc::Rc<P>
where
M: DataMarker,
P: DryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load(req)
}
}

#[cfg(target_has_atomic = "ptr")]
impl<M, P> DryDataProvider<M> for alloc::sync::Arc<P>
where
M: DataMarker,
P: DryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load(req)
}
}

/// A [`DataProvider`] that can iterate over all supported [`DataIdentifierCow`]s.
///
/// The provider is not allowed to return `Ok` for requests that were not returned by `iter_ids`,
/// and must not fail with a [`DataErrorKind::IdentifierNotFound`] for requests that were returned.
pub trait IterableDataProvider<M: DataMarker>: DataProvider<M> {
/// Returns a set of [`DataIdentifierCow`].
fn iter_ids(&self) -> Result<BTreeSet<DataIdentifierCow>, DataError>;
}

/// A data provider that loads data for a specific data type.
///
/// Unlike [`DataProvider`], there may be multiple markers corresponding to the same data type.
Expand All @@ -108,23 +153,6 @@ where
) -> Result<DataResponse<M>, DataError>;
}

/// A dynanmic data provider that can determine whether it can load a particular data identifier,
/// potentially cheaper than actually performing the load.
pub trait DynamicDryDataProvider<M: DynamicDataMarker>: DynamicDataProvider<M> {
/// This method goes through the motions of [`load_data`], but only returns the metadata.
///
/// If `dry_load_data` returns an error, [`load_data`] must return the same error, but
/// not vice-versa. Concretely, [`load_data`] could return deserialization or I/O errors
/// that `dry_load_data` cannot predict.
///
/// [`load_data`]: DynamicDataProvider::load_data
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError>;
}

impl<M, P> DynamicDataProvider<M> for &P
where
M: DynamicDataMarker,
Expand Down Expand Up @@ -186,6 +214,84 @@ where
}
}

/// A dynanmic data provider that can determine whether it can load a particular data identifier,
/// potentially cheaper than actually performing the load.
pub trait DynamicDryDataProvider<M: DynamicDataMarker>: DynamicDataProvider<M> {
/// This method goes through the motions of [`load_data`], but only returns the metadata.
///
/// If `dry_load_data` returns an error, [`load_data`] must return the same error, but
/// not vice-versa. Concretely, [`load_data`] could return deserialization or I/O errors
/// that `dry_load_data` cannot predict.
///
/// [`load_data`]: DynamicDataProvider::load_data
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError>;
}

impl<M, P> DynamicDryDataProvider<M> for &P
where
M: DynamicDataMarker,
P: DynamicDryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
(*self).dry_load_data(marker, req)
}
}

impl<M, P> DynamicDryDataProvider<M> for Box<P>
where
M: DynamicDataMarker,
P: DynamicDryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load_data(marker, req)
}
}

impl<M, P> DynamicDryDataProvider<M> for alloc::rc::Rc<P>
where
M: DynamicDataMarker,
P: DynamicDryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load_data(marker, req)
}
}

#[cfg(target_has_atomic = "ptr")]
impl<M, P> DynamicDryDataProvider<M> for alloc::sync::Arc<P>
where
M: DynamicDataMarker,
P: DynamicDryDataProvider<M> + ?Sized,
{
#[inline]
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
(**self).dry_load_data(marker, req)
}
}

/// A [`DynamicDataProvider`] that can iterate over all supported [`DataIdentifierCow`]s for a certain marker.
///
/// The provider is not allowed to return `Ok` for requests that were not returned by `iter_ids`,
Expand Down

0 comments on commit ff90048

Please sign in to comment.