Make AssetLoader/Saver Error type bounds compatible with anyhow::Error (#10493)

# Objective

* In Bevy 0.11 asset loaders used `anyhow::Error` for returning errors.
In Bevy 0.12 `AssetLoader` (and `AssetSaver`) have associated `Error`
type. Unfortunately it's type bounds does not allow `anyhow::Error` to
be used despite migration guide claiming otherwise. This makes migration
to 0.12 more challenging. Solve this by changing type bounds for
associated `Error` type.
* Fix #10350

## Solution

Change associated `Error` type bounds to require `Into<Box<dyn
std::error::Error + Send + Sync + 'static>>` to be implemented instead
of `std::error::Error + Send + Sync + 'static`. Both `anyhow::Error` and
errors generated by `thiserror` seems to be fine with such type bound.

---

## Changelog

### Fixed
* Fixed compatibility with `anyhow::Error` in `AssetLoader` and
`AssetSaver` associated `Error` type
This commit is contained in:
Rafał Harabień 2023-11-14 02:25:06 +01:00 committed by Carter Anderson
parent 6ebc0a2dfb
commit e69ab92baf
3 changed files with 9 additions and 5 deletions

View file

@ -28,7 +28,7 @@ pub trait AssetLoader: Send + Sync + 'static {
/// The settings type used by this [`AssetLoader`]. /// The settings type used by this [`AssetLoader`].
type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>; type Settings: Settings + Default + Serialize + for<'a> Deserialize<'a>;
/// The type of [error](`std::error::Error`) which could be encountered by this loader. /// The type of [error](`std::error::Error`) which could be encountered by this loader.
type Error: std::error::Error + Send + Sync + 'static; type Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>;
/// Asynchronously loads [`AssetLoader::Asset`] (and any other labeled assets) from the bytes provided by [`Reader`]. /// Asynchronously loads [`AssetLoader::Asset`] (and any other labeled assets) from the bytes provided by [`Reader`].
fn load<'a>( fn load<'a>(
&'a self, &'a self,
@ -90,7 +90,9 @@ where
.expect("Loader settings should exist") .expect("Loader settings should exist")
.downcast_ref::<L::Settings>() .downcast_ref::<L::Settings>()
.expect("AssetLoader settings should match the loader type"); .expect("AssetLoader settings should match the loader type");
let asset = <L as AssetLoader>::load(self, reader, settings, &mut load_context).await?; let asset = <L as AssetLoader>::load(self, reader, settings, &mut load_context)
.await
.map_err(|error| error.into())?;
Ok(load_context.finish(asset, Some(meta)).into()) Ok(load_context.finish(asset, Some(meta)).into())
}) })
} }

View file

@ -138,7 +138,7 @@ impl<Loader: AssetLoader, Saver: AssetSaver<Asset = Loader::Asset>> Process
.saver .saver
.save(writer, saved_asset, &settings.saver_settings) .save(writer, saved_asset, &settings.saver_settings)
.await .await
.map_err(|error| ProcessError::AssetSaveError(Box::new(error)))?; .map_err(|error| ProcessError::AssetSaveError(error.into()))?;
Ok(output_settings) Ok(output_settings)
}) })
} }

View file

@ -14,7 +14,7 @@ pub trait AssetSaver: Send + Sync + 'static {
/// The type of [`AssetLoader`] used to load this [`Asset`] /// The type of [`AssetLoader`] used to load this [`Asset`]
type OutputLoader: AssetLoader; type OutputLoader: AssetLoader;
/// The type of [error](`std::error::Error`) which could be encountered by this saver. /// The type of [error](`std::error::Error`) which could be encountered by this saver.
type Error: std::error::Error + Send + Sync + 'static; type Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>;
/// Saves the given runtime [`Asset`] by writing it to a byte format using `writer`. The passed in `settings` can influence how the /// Saves the given runtime [`Asset`] by writing it to a byte format using `writer`. The passed in `settings` can influence how the
/// `asset` is saved. /// `asset` is saved.
@ -53,7 +53,9 @@ impl<S: AssetSaver> ErasedAssetSaver for S {
.downcast_ref::<S::Settings>() .downcast_ref::<S::Settings>()
.expect("AssetLoader settings should match the loader type"); .expect("AssetLoader settings should match the loader type");
let saved_asset = SavedAsset::<S::Asset>::from_loaded(asset).unwrap(); let saved_asset = SavedAsset::<S::Asset>::from_loaded(asset).unwrap();
self.save(writer, saved_asset, settings).await?; if let Err(err) = self.save(writer, saved_asset, settings).await {
return Err(err.into());
}
Ok(()) Ok(())
}) })
} }