Deny derive_more error feature and replace it with thiserror (#16684)

# Objective

- Remove `derive_more`'s error derivation and replace it with
`thiserror`

## Solution

- Added `derive_more`'s `error` feature to `deny.toml` to prevent it
sneaking back in.
- Reverted to `thiserror` error derivation

## Notes

Merge conflicts were too numerous to revert the individual changes, so
this reversion was done manually. Please scrutinise carefully during
review.
This commit is contained in:
Zachary Harrold 2024-12-07 04:03:55 +11:00 committed by GitHub
parent d0afdc6b45
commit a6adced9ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 668 additions and 766 deletions

View file

@ -34,11 +34,8 @@ ron = "0.8"
serde = "1" serde = "1"
blake3 = { version = "1.0" } blake3 = { version = "1.0" }
downcast-rs = "1.2.0" downcast-rs = "1.2.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
either = "1.13" either = "1.13"
thread_local = "1" thread_local = "1"
uuid = { version = "1.7", features = ["v4"] } uuid = { version = "1.7", features = ["v4"] }

View file

@ -5,8 +5,8 @@ use bevy_math::{
vec4, Quat, Vec4, VectorSpace, vec4, Quat, Vec4, VectorSpace,
}; };
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use derive_more::derive::{Display, Error, From};
use either::Either; use either::Either;
use thiserror::Error;
/// A keyframe-defined curve that "interpolates" by stepping at `t = 1.0` to the next keyframe. /// A keyframe-defined curve that "interpolates" by stepping at `t = 1.0` to the next keyframe.
#[derive(Debug, Clone, Reflect)] #[derive(Debug, Clone, Reflect)]
@ -319,11 +319,11 @@ where
} }
/// An error indicating that a multisampling keyframe curve could not be constructed. /// An error indicating that a multisampling keyframe curve could not be constructed.
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
#[display("unable to construct a curve using this data")] #[error("unable to construct a curve using this data")]
pub enum WideKeyframeCurveError { pub enum WideKeyframeCurveError {
/// The number of given values was not divisible by a multiple of the number of keyframes. /// The number of given values was not divisible by a multiple of the number of keyframes.
#[display("number of values ({values_given}) is not divisible by {divisor}")] #[error("number of values ({values_given}) is not divisible by {divisor}")]
LengthMismatch { LengthMismatch {
/// The number of values given. /// The number of values given.
values_given: usize, values_given: usize,
@ -331,7 +331,8 @@ pub enum WideKeyframeCurveError {
divisor: usize, divisor: usize,
}, },
/// An error was returned by the internal core constructor. /// An error was returned by the internal core constructor.
CoreError(ChunkedUnevenCoreError), #[error(transparent)]
CoreError(#[from] ChunkedUnevenCoreError),
} }
impl<T> WideCubicKeyframeCurve<T> { impl<T> WideCubicKeyframeCurve<T> {

View file

@ -16,7 +16,7 @@ use bevy_ecs::{
}; };
use bevy_reflect::{prelude::ReflectDefault, Reflect, ReflectSerialize}; use bevy_reflect::{prelude::ReflectDefault, Reflect, ReflectSerialize};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use derive_more::derive::{Display, Error, From}; use derive_more::derive::From;
use petgraph::{ use petgraph::{
graph::{DiGraph, NodeIndex}, graph::{DiGraph, NodeIndex},
Direction, Direction,
@ -24,6 +24,7 @@ use petgraph::{
use ron::de::SpannedError; use ron::de::SpannedError;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smallvec::SmallVec; use smallvec::SmallVec;
use thiserror::Error;
use crate::{AnimationClip, AnimationTargetId}; use crate::{AnimationClip, AnimationTargetId};
@ -237,18 +238,18 @@ pub struct AnimationGraphAssetLoader;
/// Various errors that can occur when serializing or deserializing animation /// Various errors that can occur when serializing or deserializing animation
/// graphs to and from RON, respectively. /// graphs to and from RON, respectively.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum AnimationGraphLoadError { pub enum AnimationGraphLoadError {
/// An I/O error occurred. /// An I/O error occurred.
#[display("I/O")] #[error("I/O")]
Io(io::Error), Io(#[from] io::Error),
/// An error occurred in RON serialization or deserialization. /// An error occurred in RON serialization or deserialization.
#[display("RON serialization")] #[error("RON serialization")]
Ron(ron::Error), Ron(#[from] ron::Error),
/// An error occurred in RON deserialization, and the location of the error /// An error occurred in RON deserialization, and the location of the error
/// is supplied. /// is supplied.
#[display("RON serialization")] #[error("RON serialization")]
SpannedRon(SpannedError), SpannedRon(#[from] SpannedError),
} }
/// Acceleration structures for animation graphs that allows Bevy to evaluate /// Acceleration structures for animation graphs that allows Bevy to evaluate

View file

@ -29,11 +29,7 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
# other # other
downcast-rs = "1.2.0" downcast-rs = "1.2.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
variadics_please = "1.0" variadics_please = "1.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]

View file

@ -15,11 +15,11 @@ use bevy_ecs::{
use bevy_utils::tracing::info_span; use bevy_utils::tracing::info_span;
use bevy_utils::{tracing::debug, HashMap}; use bevy_utils::{tracing::debug, HashMap};
use core::{fmt::Debug, num::NonZero, panic::AssertUnwindSafe}; use core::{fmt::Debug, num::NonZero, panic::AssertUnwindSafe};
use derive_more::derive::{Display, Error};
use std::{ use std::{
panic::{catch_unwind, resume_unwind}, panic::{catch_unwind, resume_unwind},
process::{ExitCode, Termination}, process::{ExitCode, Termination},
}; };
use thiserror::Error;
bevy_ecs::define_label!( bevy_ecs::define_label!(
/// A strongly-typed class of labels used to identify an [`App`]. /// A strongly-typed class of labels used to identify an [`App`].
@ -32,9 +32,9 @@ pub use bevy_ecs::label::DynEq;
/// A shorthand for `Interned<dyn AppLabel>`. /// A shorthand for `Interned<dyn AppLabel>`.
pub type InternedAppLabel = Interned<dyn AppLabel>; pub type InternedAppLabel = Interned<dyn AppLabel>;
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub(crate) enum AppError { pub(crate) enum AppError {
#[display("duplicate plugin {plugin_name:?}")] #[error("duplicate plugin {plugin_name:?}")]
DuplicatePlugin { plugin_name: String }, DuplicatePlugin { plugin_name: String },
} }

View file

@ -44,11 +44,8 @@ blake3 = "1.5"
parking_lot = { version = "0.12", features = ["arc_lock", "send_guard"] } parking_lot = { version = "0.12", features = ["arc_lock", "send_guard"] }
ron = "0.8" ron = "0.8"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
uuid = { version = "1.0", features = ["v4"] } uuid = { version = "1.0", features = ["v4"] }
[target.'cfg(target_os = "android")'.dependencies] [target.'cfg(target_os = "android")'.dependencies]

View file

@ -11,8 +11,8 @@ use bevy_reflect::{Reflect, TypePath};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::{any::TypeId, iter::Enumerate, marker::PhantomData, sync::atomic::AtomicU32}; use core::{any::TypeId, iter::Enumerate, marker::PhantomData, sync::atomic::AtomicU32};
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::{Receiver, Sender};
use derive_more::derive::{Display, Error};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid; use uuid::Uuid;
/// A generational runtime-only identifier for a specific [`Asset`] stored in [`Assets`]. This is optimized for efficient runtime /// A generational runtime-only identifier for a specific [`Asset`] stored in [`Assets`]. This is optimized for efficient runtime
@ -613,8 +613,8 @@ impl<'a, A: Asset> Iterator for AssetsMutIterator<'a, A> {
} }
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("AssetIndex {index:?} has an invalid generation. The current generation is: '{current_generation}'.")] #[error("AssetIndex {index:?} has an invalid generation. The current generation is: '{current_generation}'.")]
pub struct InvalidGenerationError { pub struct InvalidGenerationError {
index: AssetIndex, index: AssetIndex,
current_generation: u32, current_generation: u32,

View file

@ -9,8 +9,8 @@ use core::{
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::{Receiver, Sender};
use derive_more::derive::{Display, Error};
use disqualified::ShortName; use disqualified::ShortName;
use thiserror::Error;
use uuid::Uuid; use uuid::Uuid;
/// Provides [`Handle`] and [`UntypedHandle`] _for a specific asset type_. /// Provides [`Handle`] and [`UntypedHandle`] _for a specific asset type_.
@ -502,11 +502,11 @@ impl<A: Asset> TryFrom<UntypedHandle> for Handle<A> {
} }
/// Errors preventing the conversion of to/from an [`UntypedHandle`] and a [`Handle`]. /// Errors preventing the conversion of to/from an [`UntypedHandle`] and a [`Handle`].
#[derive(Error, Display, Debug, PartialEq, Clone)] #[derive(Error, Debug, PartialEq, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub enum UntypedAssetConversionError { pub enum UntypedAssetConversionError {
/// Caused when trying to convert an [`UntypedHandle`] into a [`Handle`] of the wrong type. /// Caused when trying to convert an [`UntypedHandle`] into a [`Handle`] of the wrong type.
#[display( #[error(
"This UntypedHandle is for {found:?} and cannot be converted into a Handle<{expected:?}>" "This UntypedHandle is for {found:?} and cannot be converted into a Handle<{expected:?}>"
)] )]
TypeIdMismatch { expected: TypeId, found: TypeId }, TypeIdMismatch { expected: TypeId, found: TypeId },

View file

@ -9,7 +9,8 @@ use core::{
hash::Hash, hash::Hash,
marker::PhantomData, marker::PhantomData,
}; };
use derive_more::derive::{Display, Error, From}; use derive_more::derive::From;
use thiserror::Error;
/// A unique runtime-only identifier for an [`Asset`]. This is cheap to [`Copy`]/[`Clone`] and is not directly tied to the /// A unique runtime-only identifier for an [`Asset`]. This is cheap to [`Copy`]/[`Clone`] and is not directly tied to the
/// lifetime of the Asset. This means it _can_ point to an [`Asset`] that no longer exists. /// lifetime of the Asset. This means it _can_ point to an [`Asset`] that no longer exists.
@ -398,11 +399,11 @@ impl<A: Asset> TryFrom<UntypedAssetId> for AssetId<A> {
} }
/// Errors preventing the conversion of to/from an [`UntypedAssetId`] and an [`AssetId`]. /// Errors preventing the conversion of to/from an [`UntypedAssetId`] and an [`AssetId`].
#[derive(Error, Display, Debug, PartialEq, Clone)] #[derive(Error, Debug, PartialEq, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub enum UntypedAssetIdConversionError { pub enum UntypedAssetIdConversionError {
/// Caused when trying to convert an [`UntypedAssetId`] into an [`AssetId`] of the wrong type. /// Caused when trying to convert an [`UntypedAssetId`] into an [`AssetId`] of the wrong type.
#[display("This UntypedAssetId is for {found:?} and cannot be converted into an AssetId<{expected:?}>")] #[error("This UntypedAssetId is for {found:?} and cannot be converted into an AssetId<{expected:?}>")]
TypeIdMismatch { expected: TypeId, found: TypeId }, TypeIdMismatch { expected: TypeId, found: TypeId },
} }

View file

@ -29,27 +29,25 @@ use core::{
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
use derive_more::derive::{Display, Error, From};
use futures_io::{AsyncRead, AsyncWrite}; use futures_io::{AsyncRead, AsyncWrite};
use futures_lite::{ready, Stream}; use futures_lite::{ready, Stream};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
/// Errors that occur while loading assets. /// Errors that occur while loading assets.
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
pub enum AssetReaderError { pub enum AssetReaderError {
/// Path not found. /// Path not found.
#[display("Path not found: {}", _0.display())] #[error("Path not found: {}", _0.display())]
#[error(ignore)]
NotFound(PathBuf), NotFound(PathBuf),
/// Encountered an I/O error while loading an asset. /// Encountered an I/O error while loading an asset.
#[display("Encountered an I/O error while loading asset: {_0}")] #[error("Encountered an I/O error while loading asset: {0}")]
Io(Arc<std::io::Error>), Io(Arc<std::io::Error>),
/// The HTTP request completed but returned an unhandled [HTTP response status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status). /// The HTTP request completed but returned an unhandled [HTTP response status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
/// If the request fails before getting a status code (e.g. request timeout, interrupted connection, etc), expect [`AssetReaderError::Io`]. /// If the request fails before getting a status code (e.g. request timeout, interrupted connection, etc), expect [`AssetReaderError::Io`].
#[display("Encountered HTTP status {_0:?} when loading asset")] #[error("Encountered HTTP status {0:?} when loading asset")]
#[error(ignore)]
HttpError(u16), HttpError(u16),
} }
@ -333,11 +331,11 @@ pub type Writer = dyn AsyncWrite + Unpin + Send + Sync;
pub type PathStream = dyn Stream<Item = PathBuf> + Unpin + Send; pub type PathStream = dyn Stream<Item = PathBuf> + Unpin + Send;
/// Errors that occur while loading assets. /// Errors that occur while loading assets.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum AssetWriterError { pub enum AssetWriterError {
/// Encountered an I/O error while loading an asset. /// Encountered an I/O error while loading an asset.
#[display("encountered an io error while loading asset: {_0}")] #[error("encountered an io error while loading asset: {0}")]
Io(std::io::Error), Io(#[from] std::io::Error),
} }
/// Preforms write operations on an asset storage. [`AssetWriter`] exposes a "virtual filesystem" /// Preforms write operations on an asset storage. [`AssetWriter`] exposes a "virtual filesystem"

View file

@ -10,7 +10,7 @@ use bevy_utils::{
Duration, HashMap, Duration, HashMap,
}; };
use core::{fmt::Display, hash::Hash}; use core::{fmt::Display, hash::Hash};
use derive_more::derive::{Display, Error}; use thiserror::Error;
use super::{ErasedAssetReader, ErasedAssetWriter}; use super::{ErasedAssetReader, ErasedAssetWriter};
@ -629,27 +629,23 @@ impl AssetSources {
} }
/// An error returned when an [`AssetSource`] does not exist for a given id. /// An error returned when an [`AssetSource`] does not exist for a given id.
#[derive(Error, Display, Debug, Clone, PartialEq, Eq)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
#[display("Asset Source '{_0}' does not exist")] #[error("Asset Source '{0}' does not exist")]
#[error(ignore)]
pub struct MissingAssetSourceError(AssetSourceId<'static>); pub struct MissingAssetSourceError(AssetSourceId<'static>);
/// An error returned when an [`AssetWriter`](crate::io::AssetWriter) does not exist for a given id. /// An error returned when an [`AssetWriter`](crate::io::AssetWriter) does not exist for a given id.
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
#[display("Asset Source '{_0}' does not have an AssetWriter.")] #[error("Asset Source '{0}' does not have an AssetWriter.")]
#[error(ignore)]
pub struct MissingAssetWriterError(AssetSourceId<'static>); pub struct MissingAssetWriterError(AssetSourceId<'static>);
/// An error returned when a processed [`AssetReader`](crate::io::AssetReader) does not exist for a given id. /// An error returned when a processed [`AssetReader`](crate::io::AssetReader) does not exist for a given id.
#[derive(Error, Display, Debug, Clone, PartialEq, Eq)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
#[display("Asset Source '{_0}' does not have a processed AssetReader.")] #[error("Asset Source '{0}' does not have a processed AssetReader.")]
#[error(ignore)]
pub struct MissingProcessedAssetReaderError(AssetSourceId<'static>); pub struct MissingProcessedAssetReaderError(AssetSourceId<'static>);
/// An error returned when a processed [`AssetWriter`](crate::io::AssetWriter) does not exist for a given id. /// An error returned when a processed [`AssetWriter`](crate::io::AssetWriter) does not exist for a given id.
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
#[display("Asset Source '{_0}' does not have a processed AssetWriter.")] #[error("Asset Source '{0}' does not have a processed AssetWriter.")]
#[error(ignore)]
pub struct MissingProcessedAssetWriterError(AssetSourceId<'static>); pub struct MissingProcessedAssetWriterError(AssetSourceId<'static>);
const MISSING_DEFAULT_SOURCE: &str = const MISSING_DEFAULT_SOURCE: &str =

View file

@ -630,9 +630,9 @@ mod tests {
use bevy_log::LogPlugin; use bevy_log::LogPlugin;
use bevy_reflect::TypePath; use bevy_reflect::TypePath;
use bevy_utils::{Duration, HashMap}; use bevy_utils::{Duration, HashMap};
use derive_more::derive::{Display, Error, From};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::Path; use std::path::Path;
use thiserror::Error;
#[derive(Asset, TypePath, Debug, Default)] #[derive(Asset, TypePath, Debug, Default)]
pub struct CoolText { pub struct CoolText {
@ -660,14 +660,14 @@ mod tests {
#[derive(Default)] #[derive(Default)]
pub struct CoolTextLoader; pub struct CoolTextLoader;
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum CoolTextLoaderError { pub enum CoolTextLoaderError {
#[display("Could not load dependency: {dependency}")] #[error("Could not load dependency: {dependency}")]
CannotLoadDependency { dependency: AssetPath<'static> }, CannotLoadDependency { dependency: AssetPath<'static> },
#[display("A RON error occurred during loading")] #[error("A RON error occurred during loading")]
RonSpannedError(ron::error::SpannedError), RonSpannedError(#[from] ron::error::SpannedError),
#[display("An IO error occurred during loading")] #[error("An IO error occurred during loading")]
Io(std::io::Error), Io(#[from] std::io::Error),
} }
impl AssetLoader for CoolTextLoader { impl AssetLoader for CoolTextLoader {

View file

@ -10,11 +10,11 @@ use atomicow::CowArc;
use bevy_ecs::world::World; use bevy_ecs::world::World;
use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap, HashSet}; use bevy_utils::{BoxedFuture, ConditionalSendFuture, HashMap, HashSet};
use core::any::{Any, TypeId}; use core::any::{Any, TypeId};
use derive_more::derive::{Display, Error, From};
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
use ron::error::SpannedError; use ron::error::SpannedError;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
/// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`] /// Loads an [`Asset`] from a given byte [`Reader`]. This can accept [`AssetLoader::Settings`], which configure how the [`Asset`]
/// should be loaded. /// should be loaded.
@ -295,20 +295,19 @@ impl<A: Asset> AssetContainer for A {
/// ///
/// [`NestedLoader::load`]: crate::NestedLoader::load /// [`NestedLoader::load`]: crate::NestedLoader::load
/// [immediately]: crate::Immediate /// [immediately]: crate::Immediate
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("Failed to load dependency {dependency:?} {error}")] #[error("Failed to load dependency {dependency:?} {error}")]
pub struct LoadDirectError { pub struct LoadDirectError {
pub dependency: AssetPath<'static>, pub dependency: AssetPath<'static>,
pub error: AssetLoadError, pub error: AssetLoadError,
} }
/// An error that occurs while deserializing [`AssetMeta`]. /// An error that occurs while deserializing [`AssetMeta`].
#[derive(Error, Display, Debug, Clone, PartialEq, Eq, From)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum DeserializeMetaError { pub enum DeserializeMetaError {
#[display("Failed to deserialize asset meta: {_0:?}")] #[error("Failed to deserialize asset meta: {0:?}")]
DeserializeSettings(SpannedError), DeserializeSettings(#[from] SpannedError),
#[display("Failed to deserialize minimal asset meta: {_0:?}")] #[error("Failed to deserialize minimal asset meta: {0:?}")]
#[from(ignore)]
DeserializeMinimal(SpannedError), DeserializeMinimal(SpannedError),
} }
@ -573,18 +572,22 @@ impl<'a> LoadContext<'a> {
} }
/// An error produced when calling [`LoadContext::read_asset_bytes`] /// An error produced when calling [`LoadContext::read_asset_bytes`]
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum ReadAssetBytesError { pub enum ReadAssetBytesError {
DeserializeMetaError(DeserializeMetaError), #[error(transparent)]
AssetReaderError(AssetReaderError), DeserializeMetaError(#[from] DeserializeMetaError),
MissingAssetSourceError(MissingAssetSourceError), #[error(transparent)]
MissingProcessedAssetReaderError(MissingProcessedAssetReaderError), AssetReaderError(#[from] AssetReaderError),
#[error(transparent)]
MissingAssetSourceError(#[from] MissingAssetSourceError),
#[error(transparent)]
MissingProcessedAssetReaderError(#[from] MissingProcessedAssetReaderError),
/// Encountered an I/O error while loading an asset. /// Encountered an I/O error while loading an asset.
#[display("Encountered an io error while loading asset at `{}`: {source}", path.display())] #[error("Encountered an io error while loading asset at `{}`: {source}", path.display())]
Io { Io {
path: PathBuf, path: PathBuf,
source: std::io::Error, source: std::io::Error,
}, },
#[display("The LoadContext for this read_asset_bytes call requires hash metadata, but it was not provided. This is likely an internal implementation error.")] #[error("The LoadContext for this read_asset_bytes call requires hash metadata, but it was not provided. This is likely an internal implementation error.")]
MissingAssetHash, MissingAssetHash,
} }

View file

@ -6,9 +6,9 @@ use core::{
hash::Hash, hash::Hash,
ops::Deref, ops::Deref,
}; };
use derive_more::derive::{Display, Error};
use serde::{de::Visitor, Deserialize, Serialize}; use serde::{de::Visitor, Deserialize, Serialize};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
/// Represents a path to an asset in a "virtual filesystem". /// Represents a path to an asset in a "virtual filesystem".
/// ///
@ -76,19 +76,19 @@ impl<'a> Display for AssetPath<'a> {
} }
/// An error that occurs when parsing a string type to create an [`AssetPath`] fails, such as during [`AssetPath::parse`]. /// An error that occurs when parsing a string type to create an [`AssetPath`] fails, such as during [`AssetPath::parse`].
#[derive(Error, Display, Debug, PartialEq, Eq)] #[derive(Error, Debug, PartialEq, Eq)]
pub enum ParseAssetPathError { pub enum ParseAssetPathError {
/// Error that occurs when the [`AssetPath::source`] section of a path string contains the [`AssetPath::label`] delimiter `#`. E.g. `bad#source://file.test`. /// Error that occurs when the [`AssetPath::source`] section of a path string contains the [`AssetPath::label`] delimiter `#`. E.g. `bad#source://file.test`.
#[display("Asset source must not contain a `#` character")] #[error("Asset source must not contain a `#` character")]
InvalidSourceSyntax, InvalidSourceSyntax,
/// Error that occurs when the [`AssetPath::label`] section of a path string contains the [`AssetPath::source`] delimiter `://`. E.g. `source://file.test#bad://label`. /// Error that occurs when the [`AssetPath::label`] section of a path string contains the [`AssetPath::source`] delimiter `://`. E.g. `source://file.test#bad://label`.
#[display("Asset label must not contain a `://` substring")] #[error("Asset label must not contain a `://` substring")]
InvalidLabelSyntax, InvalidLabelSyntax,
/// Error that occurs when a path string has an [`AssetPath::source`] delimiter `://` with no characters preceding it. E.g. `://file.test`. /// Error that occurs when a path string has an [`AssetPath::source`] delimiter `://` with no characters preceding it. E.g. `://file.test`.
#[display("Asset source must be at least one character. Either specify the source before the '://' or remove the `://`")] #[error("Asset source must be at least one character. Either specify the source before the '://' or remove the `://`")]
MissingSource, MissingSource,
/// Error that occurs when a path string has an [`AssetPath::label`] delimiter `#` with no characters succeeding it. E.g. `file.test#` /// Error that occurs when a path string has an [`AssetPath::label`] delimiter `#` with no characters succeeding it. E.g. `file.test#`
#[display("Asset label must be at least one character. Either specify the label after the '#' or remove the '#'")] #[error("Asset label must be at least one character. Either specify the label after the '#' or remove the '#'")]
MissingLabel, MissingLabel,
} }

View file

@ -1,9 +1,9 @@
use crate::AssetPath; use crate::AssetPath;
use async_fs::File; use async_fs::File;
use bevy_utils::{tracing::error, HashSet}; use bevy_utils::{tracing::error, HashSet};
use derive_more::derive::{Display, Error, From};
use futures_lite::{AsyncReadExt, AsyncWriteExt}; use futures_lite::{AsyncReadExt, AsyncWriteExt};
use std::path::PathBuf; use std::path::PathBuf;
use thiserror::Error;
/// An in-memory representation of a single [`ProcessorTransactionLog`] entry. /// An in-memory representation of a single [`ProcessorTransactionLog`] entry.
#[derive(Debug)] #[derive(Debug)]
@ -24,18 +24,17 @@ pub struct ProcessorTransactionLog {
} }
/// An error that occurs when reading from the [`ProcessorTransactionLog`] fails. /// An error that occurs when reading from the [`ProcessorTransactionLog`] fails.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum ReadLogError { pub enum ReadLogError {
#[display("Encountered an invalid log line: '{_0}'")] #[error("Encountered an invalid log line: '{0}'")]
#[error(ignore)]
InvalidLine(String), InvalidLine(String),
#[display("Failed to read log file: {_0}")] #[error("Failed to read log file: {0}")]
Io(futures_io::Error), Io(#[from] futures_io::Error),
} }
/// An error that occurs when writing to the [`ProcessorTransactionLog`] fails. /// An error that occurs when writing to the [`ProcessorTransactionLog`] fails.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display( #[error(
"Failed to write {log_entry:?} to the asset processor log. This is not recoverable. {error}" "Failed to write {log_entry:?} to the asset processor log. This is not recoverable. {error}"
)] )]
pub struct WriteLogError { pub struct WriteLogError {
@ -44,27 +43,24 @@ pub struct WriteLogError {
} }
/// An error that occurs when validating the [`ProcessorTransactionLog`] fails. /// An error that occurs when validating the [`ProcessorTransactionLog`] fails.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum ValidateLogError { pub enum ValidateLogError {
#[display("Encountered an unrecoverable error. All assets will be reprocessed.")] #[error("Encountered an unrecoverable error. All assets will be reprocessed.")]
UnrecoverableError, UnrecoverableError,
ReadLogError(ReadLogError), #[error(transparent)]
#[display("Encountered a duplicate process asset transaction: {_0:?}")] ReadLogError(#[from] ReadLogError),
#[error(ignore)] #[error("Encountered a duplicate process asset transaction: {0:?}")]
EntryErrors(Vec<LogEntryError>), EntryErrors(Vec<LogEntryError>),
} }
/// An error that occurs when validating individual [`ProcessorTransactionLog`] entries. /// An error that occurs when validating individual [`ProcessorTransactionLog`] entries.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum LogEntryError { pub enum LogEntryError {
#[display("Encountered a duplicate process asset transaction: {_0}")] #[error("Encountered a duplicate process asset transaction: {0}")]
#[error(ignore)]
DuplicateTransaction(AssetPath<'static>), DuplicateTransaction(AssetPath<'static>),
#[display("A transaction was ended that never started {_0}")] #[error("A transaction was ended that never started {0}")]
#[error(ignore)]
EndedMissingTransaction(AssetPath<'static>), EndedMissingTransaction(AssetPath<'static>),
#[display("An asset started processing but never finished: {_0}")] #[error("An asset started processing but never finished: {0}")]
#[error(ignore)]
UnfinishedTransaction(AssetPath<'static>), UnfinishedTransaction(AssetPath<'static>),
} }

View file

@ -68,11 +68,11 @@ use bevy_utils::{
tracing::{info_span, instrument::Instrument}, tracing::{info_span, instrument::Instrument},
ConditionalSendFuture, ConditionalSendFuture,
}; };
use derive_more::derive::{Display, Error};
use futures_io::ErrorKind; use futures_io::ErrorKind;
use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt}; use futures_lite::{AsyncReadExt, AsyncWriteExt, StreamExt};
use parking_lot::RwLock; use parking_lot::RwLock;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
/// A "background" asset processor that reads asset values from a source [`AssetSource`] (which corresponds to an [`AssetReader`](crate::io::AssetReader) / [`AssetWriter`](crate::io::AssetWriter) pair), /// A "background" asset processor that reads asset values from a source [`AssetSource`] (which corresponds to an [`AssetReader`](crate::io::AssetReader) / [`AssetWriter`](crate::io::AssetWriter) pair),
/// processes them in some way, and writes them to a destination [`AssetSource`]. /// processes them in some way, and writes them to a destination [`AssetSource`].
@ -1413,10 +1413,12 @@ pub enum ProcessorState {
} }
/// An error that occurs when initializing the [`AssetProcessor`]. /// An error that occurs when initializing the [`AssetProcessor`].
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum InitializeError { pub enum InitializeError {
#[error(transparent)]
FailedToReadSourcePaths(AssetReaderError), FailedToReadSourcePaths(AssetReaderError),
#[error(transparent)]
FailedToReadDestinationPaths(AssetReaderError), FailedToReadDestinationPaths(AssetReaderError),
#[display("Failed to validate asset log: {_0}")] #[error("Failed to validate asset log: {0}")]
ValidateLogError(ValidateLogError), ValidateLogError(#[from] ValidateLogError),
} }

View file

@ -12,8 +12,8 @@ use crate::{
}; };
use bevy_utils::{BoxedFuture, ConditionalSendFuture}; use bevy_utils::{BoxedFuture, ConditionalSendFuture};
use core::marker::PhantomData; use core::marker::PhantomData;
use derive_more::derive::{Display, Error, From};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error;
/// Asset "processor" logic that reads input asset bytes (stored on [`ProcessContext`]), processes the value in some way, /// Asset "processor" logic that reads input asset bytes (stored on [`ProcessContext`]), processes the value in some way,
/// and then writes the final processed bytes with [`Writer`]. The resulting bytes must be loadable with the given [`Process::OutputLoader`]. /// and then writes the final processed bytes with [`Writer`]. The resulting bytes must be loadable with the given [`Process::OutputLoader`].
@ -126,46 +126,52 @@ pub type LoadAndSaveSettings<LoaderSettings, SaverSettings> =
LoadTransformAndSaveSettings<LoaderSettings, (), SaverSettings>; LoadTransformAndSaveSettings<LoaderSettings, (), SaverSettings>;
/// An error that is encountered during [`Process::process`]. /// An error that is encountered during [`Process::process`].
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum ProcessError { pub enum ProcessError {
MissingAssetLoaderForExtension(MissingAssetLoaderForExtensionError), #[error(transparent)]
MissingAssetLoaderForTypeName(MissingAssetLoaderForTypeNameError), MissingAssetLoaderForExtension(#[from] MissingAssetLoaderForExtensionError),
#[display("The processor '{_0}' does not exist")] #[error(transparent)]
#[error(ignore)] MissingAssetLoaderForTypeName(#[from] MissingAssetLoaderForTypeNameError),
#[error("The processor '{0}' does not exist")]
#[from(ignore)] #[from(ignore)]
MissingProcessor(String), MissingProcessor(String),
#[display("Encountered an AssetReader error for '{path}': {err}")] #[error("Encountered an AssetReader error for '{path}': {err}")]
#[from(ignore)] #[from(ignore)]
AssetReaderError { AssetReaderError {
path: AssetPath<'static>, path: AssetPath<'static>,
err: AssetReaderError, err: AssetReaderError,
}, },
#[display("Encountered an AssetWriter error for '{path}': {err}")] #[error("Encountered an AssetWriter error for '{path}': {err}")]
#[from(ignore)] #[from(ignore)]
AssetWriterError { AssetWriterError {
path: AssetPath<'static>, path: AssetPath<'static>,
err: AssetWriterError, err: AssetWriterError,
}, },
MissingAssetWriterError(MissingAssetWriterError), #[error(transparent)]
MissingProcessedAssetReaderError(MissingProcessedAssetReaderError), MissingAssetWriterError(#[from] MissingAssetWriterError),
MissingProcessedAssetWriterError(MissingProcessedAssetWriterError), #[error(transparent)]
#[display("Failed to read asset metadata for {path}: {err}")] MissingProcessedAssetReaderError(#[from] MissingProcessedAssetReaderError),
#[error(transparent)]
MissingProcessedAssetWriterError(#[from] MissingProcessedAssetWriterError),
#[error("Failed to read asset metadata for {path}: {err}")]
#[from(ignore)] #[from(ignore)]
ReadAssetMetaError { ReadAssetMetaError {
path: AssetPath<'static>, path: AssetPath<'static>,
err: AssetReaderError, err: AssetReaderError,
}, },
DeserializeMetaError(DeserializeMetaError), #[error(transparent)]
AssetLoadError(AssetLoadError), DeserializeMetaError(#[from] DeserializeMetaError),
#[display("The wrong meta type was passed into a processor. This is probably an internal implementation error.")] #[error(transparent)]
AssetLoadError(#[from] AssetLoadError),
#[error("The wrong meta type was passed into a processor. This is probably an internal implementation error.")]
WrongMetaType, WrongMetaType,
#[display("Encountered an error while saving the asset: {_0}")] #[error("Encountered an error while saving the asset: {0}")]
#[from(ignore)] #[from(ignore)]
AssetSaveError(Box<dyn core::error::Error + Send + Sync + 'static>), AssetSaveError(Box<dyn core::error::Error + Send + Sync + 'static>),
#[display("Encountered an error while transforming the asset: {_0}")] #[error("Encountered an error while transforming the asset: {0}")]
#[from(ignore)] #[from(ignore)]
AssetTransformError(Box<dyn core::error::Error + Send + Sync + 'static>), AssetTransformError(Box<dyn core::error::Error + Send + Sync + 'static>),
#[display("Assets without extensions are not supported.")] #[error("Assets without extensions are not supported.")]
ExtensionRequired, ExtensionRequired,
} }

View file

@ -10,8 +10,8 @@ use bevy_tasks::Task;
use bevy_utils::{tracing::warn, Entry, HashMap, HashSet, TypeIdMap}; use bevy_utils::{tracing::warn, Entry, HashMap, HashSet, TypeIdMap};
use core::{any::TypeId, task::Waker}; use core::{any::TypeId, task::Waker};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use derive_more::derive::{Display, Error, From};
use either::Either; use either::Either;
use thiserror::Error;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct AssetInfo { pub(crate) struct AssetInfo {
@ -757,16 +757,16 @@ pub(crate) enum HandleLoadingMode {
Force, Force,
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("Cannot allocate a handle because no handle provider exists for asset type {_0:?}")] #[error("Cannot allocate a handle because no handle provider exists for asset type {0:?}")]
#[error(ignore)]
pub struct MissingHandleProviderError(TypeId); pub struct MissingHandleProviderError(TypeId);
/// An error encountered during [`AssetInfos::get_or_create_path_handle_internal`]. /// An error encountered during [`AssetInfos::get_or_create_path_handle_internal`].
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub(crate) enum GetOrCreateHandleInternalError { pub(crate) enum GetOrCreateHandleInternalError {
MissingHandleProviderError(MissingHandleProviderError), #[error(transparent)]
#[display("Handle does not exist but TypeId was not specified.")] MissingHandleProviderError(#[from] MissingHandleProviderError),
#[error("Handle does not exist but TypeId was not specified.")]
HandleMissingButTypeIdNotSpecified, HandleMissingButTypeIdNotSpecified,
} }

View file

@ -12,7 +12,7 @@ use bevy_utils::{
ConditionalSendFuture, ConditionalSendFuture,
}; };
use core::any::TypeId; use core::any::TypeId;
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
#[derive(Default)] #[derive(Default)]
pub(crate) struct AssetLoaders { pub(crate) struct AssetLoaders {
@ -275,9 +275,10 @@ impl AssetLoaders {
} }
} }
#[derive(Error, Display, Debug, Clone, From)] #[derive(Error, Debug, Clone)]
pub(crate) enum GetLoaderError { pub(crate) enum GetLoaderError {
CouldNotResolve(RecvError), #[error(transparent)]
CouldNotResolve(#[from] RecvError),
} }
#[derive(Clone)] #[derive(Clone)]

View file

@ -27,13 +27,13 @@ use bevy_utils::{
}; };
use core::{any::TypeId, future::Future, panic::AssertUnwindSafe, task::Poll}; use core::{any::TypeId, future::Future, panic::AssertUnwindSafe, task::Poll};
use crossbeam_channel::{Receiver, Sender}; use crossbeam_channel::{Receiver, Sender};
use derive_more::derive::{Display, Error, From};
use either::Either; use either::Either;
use futures_lite::{FutureExt, StreamExt}; use futures_lite::{FutureExt, StreamExt};
use info::*; use info::*;
use loaders::*; use loaders::*;
use parking_lot::{RwLock, RwLockWriteGuard}; use parking_lot::{RwLock, RwLockWriteGuard};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
/// Loads and tracks the state of [`Asset`] values from a configured [`AssetReader`](crate::io::AssetReader). This can be used to kick off new asset loads and /// Loads and tracks the state of [`Asset`] values from a configured [`AssetReader`](crate::io::AssetReader). This can be used to kick off new asset loads and
/// retrieve their current load states. /// retrieve their current load states.
@ -1722,53 +1722,57 @@ impl RecursiveDependencyLoadState {
} }
/// An error that occurs during an [`Asset`] load. /// An error that occurs during an [`Asset`] load.
#[derive(Error, Display, Debug, Clone, From)] #[derive(Error, Debug, Clone)]
pub enum AssetLoadError { pub enum AssetLoadError {
#[display("Requested handle of type {requested:?} for asset '{path}' does not match actual asset type '{actual_asset_name}', which used loader '{loader_name}'")] #[error("Requested handle of type {requested:?} for asset '{path}' does not match actual asset type '{actual_asset_name}', which used loader '{loader_name}'")]
RequestedHandleTypeMismatch { RequestedHandleTypeMismatch {
path: AssetPath<'static>, path: AssetPath<'static>,
requested: TypeId, requested: TypeId,
actual_asset_name: &'static str, actual_asset_name: &'static str,
loader_name: &'static str, loader_name: &'static str,
}, },
#[display("Could not find an asset loader matching: Loader Name: {loader_name:?}; Asset Type: {loader_name:?}; Extension: {extension:?}; Path: {asset_path:?};")] #[error("Could not find an asset loader matching: Loader Name: {loader_name:?}; Asset Type: {loader_name:?}; Extension: {extension:?}; Path: {asset_path:?};")]
MissingAssetLoader { MissingAssetLoader {
loader_name: Option<String>, loader_name: Option<String>,
asset_type_id: Option<TypeId>, asset_type_id: Option<TypeId>,
extension: Option<String>, extension: Option<String>,
asset_path: Option<String>, asset_path: Option<String>,
}, },
MissingAssetLoaderForExtension(MissingAssetLoaderForExtensionError), #[error(transparent)]
MissingAssetLoaderForTypeName(MissingAssetLoaderForTypeNameError), MissingAssetLoaderForExtension(#[from] MissingAssetLoaderForExtensionError),
MissingAssetLoaderForTypeIdError(MissingAssetLoaderForTypeIdError), #[error(transparent)]
AssetReaderError(AssetReaderError), MissingAssetLoaderForTypeName(#[from] MissingAssetLoaderForTypeNameError),
MissingAssetSourceError(MissingAssetSourceError), #[error(transparent)]
MissingProcessedAssetReaderError(MissingProcessedAssetReaderError), MissingAssetLoaderForTypeIdError(#[from] MissingAssetLoaderForTypeIdError),
#[display("Encountered an error while reading asset metadata bytes")] #[error(transparent)]
AssetReaderError(#[from] AssetReaderError),
#[error(transparent)]
MissingAssetSourceError(#[from] MissingAssetSourceError),
#[error(transparent)]
MissingProcessedAssetReaderError(#[from] MissingProcessedAssetReaderError),
#[error("Encountered an error while reading asset metadata bytes")]
AssetMetaReadError, AssetMetaReadError,
#[display("Failed to deserialize meta for asset {path}: {error}")] #[error("Failed to deserialize meta for asset {path}: {error}")]
DeserializeMeta { DeserializeMeta {
path: AssetPath<'static>, path: AssetPath<'static>,
error: Box<DeserializeMetaError>, error: Box<DeserializeMetaError>,
}, },
#[display("Asset '{path}' is configured to be processed. It cannot be loaded directly.")] #[error("Asset '{path}' is configured to be processed. It cannot be loaded directly.")]
#[from(ignore)] #[from(ignore)]
CannotLoadProcessedAsset { CannotLoadProcessedAsset { path: AssetPath<'static> },
path: AssetPath<'static>, #[error("Asset '{path}' is configured to be ignored. It cannot be loaded.")]
},
#[display("Asset '{path}' is configured to be ignored. It cannot be loaded.")]
#[from(ignore)] #[from(ignore)]
CannotLoadIgnoredAsset { CannotLoadIgnoredAsset { path: AssetPath<'static> },
path: AssetPath<'static>, #[error("Failed to load asset '{path}', asset loader '{loader_name}' panicked")]
},
#[display("Failed to load asset '{path}', asset loader '{loader_name}' panicked")]
AssetLoaderPanic { AssetLoaderPanic {
path: AssetPath<'static>, path: AssetPath<'static>,
loader_name: &'static str, loader_name: &'static str,
}, },
AssetLoaderError(AssetLoaderError), #[error(transparent)]
AddAsyncError(AddAsyncError), AssetLoaderError(#[from] AssetLoaderError),
#[display("The file at '{}' does not contain the labeled asset '{}'; it contains the following {} assets: {}", #[error(transparent)]
AddAsyncError(#[from] AddAsyncError),
#[error("The file at '{}' does not contain the labeled asset '{}'; it contains the following {} assets: {}",
base_path, base_path,
label, label,
all_labels.len(), all_labels.len(),
@ -1780,8 +1784,8 @@ pub enum AssetLoadError {
}, },
} }
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
#[display("Failed to load asset '{path}' with asset loader '{loader_name}': {error}")] #[error("Failed to load asset '{path}' with asset loader '{loader_name}': {error}")]
pub struct AssetLoaderError { pub struct AssetLoaderError {
path: AssetPath<'static>, path: AssetPath<'static>,
loader_name: &'static str, loader_name: &'static str,
@ -1794,29 +1798,29 @@ impl AssetLoaderError {
} }
} }
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
#[display("An error occurred while resolving an asset added by `add_async`: {error}")] #[error("An error occurred while resolving an asset added by `add_async`: {error}")]
pub struct AddAsyncError { pub struct AddAsyncError {
error: Arc<dyn core::error::Error + Send + Sync + 'static>, error: Arc<dyn core::error::Error + Send + Sync + 'static>,
} }
/// An error that occurs when an [`AssetLoader`] is not registered for a given extension. /// An error that occurs when an [`AssetLoader`] is not registered for a given extension.
#[derive(Error, Display, Debug, Clone, PartialEq, Eq)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
#[display("no `AssetLoader` found{}", format_missing_asset_ext(extensions))] #[error("no `AssetLoader` found{}", format_missing_asset_ext(extensions))]
pub struct MissingAssetLoaderForExtensionError { pub struct MissingAssetLoaderForExtensionError {
extensions: Vec<String>, extensions: Vec<String>,
} }
/// An error that occurs when an [`AssetLoader`] is not registered for a given [`std::any::type_name`]. /// An error that occurs when an [`AssetLoader`] is not registered for a given [`std::any::type_name`].
#[derive(Error, Display, Debug, Clone, PartialEq, Eq)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
#[display("no `AssetLoader` found with the name '{type_name}'")] #[error("no `AssetLoader` found with the name '{type_name}'")]
pub struct MissingAssetLoaderForTypeNameError { pub struct MissingAssetLoaderForTypeNameError {
type_name: String, type_name: String,
} }
/// An error that occurs when an [`AssetLoader`] is not registered for a given [`Asset`] [`TypeId`]. /// An error that occurs when an [`AssetLoader`] is not registered for a given [`Asset`] [`TypeId`].
#[derive(Error, Display, Debug, Clone, PartialEq, Eq)] #[derive(Error, Debug, Clone, PartialEq, Eq)]
#[display("no `AssetLoader` found with the ID '{type_id:?}'")] #[error("no `AssetLoader` found with the ID '{type_id:?}'")]
pub struct MissingAssetLoaderForTypeIdError { pub struct MissingAssetLoaderForTypeIdError {
pub type_id: TypeId, pub type_id: TypeId,
} }
@ -1846,10 +1850,12 @@ impl core::fmt::Debug for AssetServer {
const UNTYPED_SOURCE_SUFFIX: &str = "--untyped"; const UNTYPED_SOURCE_SUFFIX: &str = "--untyped";
/// An error when attempting to wait asynchronously for an [`Asset`] to load. /// An error when attempting to wait asynchronously for an [`Asset`] to load.
#[derive(Error, Debug, Clone, Display)] #[derive(Error, Debug, Clone)]
pub enum WaitForAssetError { pub enum WaitForAssetError {
#[display("tried to wait for an asset that is not being loaded")] #[error("tried to wait for an asset that is not being loaded")]
NotLoaded, NotLoaded,
#[error(transparent)]
Failed(Arc<AssetLoadError>), Failed(Arc<AssetLoadError>),
#[error(transparent)]
DependencyFailed(Arc<AssetLoadError>), DependencyFailed(Arc<AssetLoadError>),
} }

View file

@ -20,11 +20,8 @@ bytemuck = { version = "1", features = ["derive"] }
serde = { version = "1.0", features = [ serde = { version = "1.0", features = [
"derive", "derive",
], default-features = false, optional = true } ], default-features = false, optional = true }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
wgpu-types = { version = "23", default-features = false, optional = true } wgpu-types = { version = "23", default-features = false, optional = true }
encase = { version = "0.10", default-features = false, optional = true } encase = { version = "0.10", default-features = false, optional = true }

View file

@ -7,7 +7,7 @@ use alloc::{format, string::String};
use bevy_math::{ops, Vec3, Vec4}; use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*; use bevy_reflect::prelude::*;
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
/// Non-linear standard RGB with alpha. /// Non-linear standard RGB with alpha.
#[doc = include_str!("../docs/conversion.md")] #[doc = include_str!("../docs/conversion.md")]
@ -424,17 +424,16 @@ impl From<Srgba> for Xyza {
} }
/// Error returned if a hex string could not be parsed as a color. /// Error returned if a hex string could not be parsed as a color.
#[derive(Debug, Error, Display, PartialEq, Eq, From)] #[derive(Debug, Error, PartialEq, Eq)]
pub enum HexColorError { pub enum HexColorError {
/// Parsing error. /// Parsing error.
#[display("Invalid hex string")] #[error("Invalid hex string")]
Parse(core::num::ParseIntError), Parse(#[from] core::num::ParseIntError),
/// Invalid length. /// Invalid length.
#[display("Unexpected length of hex string")] #[error("Unexpected length of hex string")]
Length, Length,
/// Invalid character. /// Invalid character.
#[display("Invalid hex char")] #[error("Invalid hex char")]
#[error(ignore)]
Char(char), Char(char),
} }

View file

@ -41,11 +41,7 @@ bitflags = "2.3"
radsort = "0.1" radsort = "0.1"
nonmax = "0.5" nonmax = "0.5"
smallvec = "1" smallvec = "1"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
[lints] [lints]
workspace = true workspace = true

View file

@ -10,7 +10,7 @@ use bevy_render::{
}, },
renderer::{RenderDevice, RenderQueue}, renderer::{RenderDevice, RenderQueue},
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
const LUT_SIZE: usize = 256; const LUT_SIZE: usize = 256;
@ -40,16 +40,16 @@ pub struct AutoExposureCompensationCurve {
} }
/// Various errors that can occur when constructing an [`AutoExposureCompensationCurve`]. /// Various errors that can occur when constructing an [`AutoExposureCompensationCurve`].
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum AutoExposureCompensationCurveError { pub enum AutoExposureCompensationCurveError {
/// The curve couldn't be built in the first place. /// The curve couldn't be built in the first place.
#[display("curve could not be constructed from the given data")] #[error("curve could not be constructed from the given data")]
InvalidCurve, InvalidCurve,
/// A discontinuity was found in the curve. /// A discontinuity was found in the curve.
#[display("discontinuity found between curve segments")] #[error("discontinuity found between curve segments")]
DiscontinuityFound, DiscontinuityFound,
/// The curve is not monotonically increasing on the x-axis. /// The curve is not monotonically increasing on the x-axis.
#[display("curve is not monotonically increasing on the x-axis")] #[error("curve is not monotonically increasing on the x-axis")]
NotMonotonic, NotMonotonic,
} }

View file

@ -32,8 +32,8 @@ concurrent-queue = "2.5.0"
disqualified = "1.0" disqualified = "1.0"
fixedbitset = "0.5" fixedbitset = "0.5"
serde = { version = "1", optional = true, default-features = false } serde = { version = "1", optional = true, default-features = false }
thiserror = { version = "2", default-features = false }
derive_more = { version = "1", default-features = false, features = [ derive_more = { version = "1", default-features = false, features = [
"error",
"from", "from",
"display", "display",
"into", "into",

View file

@ -27,7 +27,7 @@ use core::{
marker::PhantomData, marker::PhantomData,
mem::needs_drop, mem::needs_drop,
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
pub use bevy_ecs_macros::require; pub use bevy_ecs_macros::require;
@ -1836,18 +1836,14 @@ impl<T: Component> FromWorld for InitComponentId<T> {
} }
/// An error returned when the registration of a required component fails. /// An error returned when the registration of a required component fails.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum RequiredComponentsError { pub enum RequiredComponentsError {
/// The component is already a directly required component for the requiree. /// The component is already a directly required component for the requiree.
#[display("Component {0:?} already directly requires component {_1:?}")] #[error("Component {0:?} already directly requires component {1:?}")]
#[error(ignore)]
DuplicateRegistration(ComponentId, ComponentId), DuplicateRegistration(ComponentId, ComponentId),
/// An archetype with the component that requires other components already exists /// An archetype with the component that requires other components already exists
#[display( #[error("An archetype with the component {0:?} that requires other components already exists")]
"An archetype with the component {_0:?} that requires other components already exists"
)]
#[error(ignore)]
ArchetypeExists(ComponentId), ArchetypeExists(ComponentId),
} }

View file

@ -45,7 +45,7 @@ pub use bevy_ptr as ptr;
/// ///
/// This includes the most common types in this crate, re-exported for your convenience. /// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude { pub mod prelude {
#[expect(deprecated)] #[allow(deprecated)]
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
bundle::Bundle, bundle::Bundle,

View file

@ -1,4 +1,4 @@
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::{entity::Entity, world::unsafe_world_cell::UnsafeWorldCell}; use crate::{entity::Entity, world::unsafe_world_cell::UnsafeWorldCell};
@ -90,15 +90,13 @@ impl<'w> Eq for QueryEntityError<'w> {}
/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via /// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via
/// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut). /// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut).
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum QuerySingleError { pub enum QuerySingleError {
/// No entity fits the query. /// No entity fits the query.
#[display("No entities fit the query {_0}")] #[error("No entities fit the query {0}")]
#[error(ignore)]
NoEntities(&'static str), NoEntities(&'static str),
/// Multiple entities fit the query. /// Multiple entities fit the query.
#[display("Multiple entities fit the query {_0}")] #[error("Multiple entities fit the query {0}")]
#[error(ignore)]
MultipleEntities(&'static str), MultipleEntities(&'static str),
} }

View file

@ -9,9 +9,9 @@ use bevy_utils::{
tracing::{error, info, warn}, tracing::{error, info, warn},
AHasher, HashMap, HashSet, AHasher, HashMap, HashSet,
}; };
use derive_more::derive::{Display, Error};
use disqualified::ShortName; use disqualified::ShortName;
use fixedbitset::FixedBitSet; use fixedbitset::FixedBitSet;
use thiserror::Error;
use crate::{ use crate::{
self as bevy_ecs, self as bevy_ecs,
@ -1933,43 +1933,42 @@ impl ScheduleGraph {
} }
/// Category of errors encountered during schedule construction. /// Category of errors encountered during schedule construction.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[error(ignore)]
#[non_exhaustive] #[non_exhaustive]
pub enum ScheduleBuildError { pub enum ScheduleBuildError {
/// A system set contains itself. /// A system set contains itself.
#[display("System set `{_0}` contains itself.")] #[error("System set `{0}` contains itself.")]
HierarchyLoop(String), HierarchyLoop(String),
/// The hierarchy of system sets contains a cycle. /// The hierarchy of system sets contains a cycle.
#[display("System set hierarchy contains cycle(s).\n{_0}")] #[error("System set hierarchy contains cycle(s).\n{0}")]
HierarchyCycle(String), HierarchyCycle(String),
/// The hierarchy of system sets contains redundant edges. /// The hierarchy of system sets contains redundant edges.
/// ///
/// This error is disabled by default, but can be opted-in using [`ScheduleBuildSettings`]. /// This error is disabled by default, but can be opted-in using [`ScheduleBuildSettings`].
#[display("System set hierarchy contains redundant edges.\n{_0}")] #[error("System set hierarchy contains redundant edges.\n{0}")]
HierarchyRedundancy(String), HierarchyRedundancy(String),
/// A system (set) has been told to run before itself. /// A system (set) has been told to run before itself.
#[display("System set `{_0}` depends on itself.")] #[error("System set `{0}` depends on itself.")]
DependencyLoop(String), DependencyLoop(String),
/// The dependency graph contains a cycle. /// The dependency graph contains a cycle.
#[display("System dependencies contain cycle(s).\n{_0}")] #[error("System dependencies contain cycle(s).\n{0}")]
DependencyCycle(String), DependencyCycle(String),
/// Tried to order a system (set) relative to a system set it belongs to. /// Tried to order a system (set) relative to a system set it belongs to.
#[display("`{_0}` and `{_1}` have both `in_set` and `before`-`after` relationships (these might be transitive). This combination is unsolvable as a system cannot run before or after a set it belongs to.")] #[error("`{0}` and `{1}` have both `in_set` and `before`-`after` relationships (these might be transitive). This combination is unsolvable as a system cannot run before or after a set it belongs to.")]
CrossDependency(String, String), CrossDependency(String, String),
/// Tried to order system sets that share systems. /// Tried to order system sets that share systems.
#[display("`{_0}` and `{_1}` have a `before`-`after` relationship (which may be transitive) but share systems.")] #[error("`{0}` and `{1}` have a `before`-`after` relationship (which may be transitive) but share systems.")]
SetsHaveOrderButIntersect(String, String), SetsHaveOrderButIntersect(String, String),
/// Tried to order a system (set) relative to all instances of some system function. /// Tried to order a system (set) relative to all instances of some system function.
#[display("Tried to order against `{_0}` in a schedule that has more than one `{_0}` instance. `{_0}` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.")] #[error("Tried to order against `{0}` in a schedule that has more than one `{0}` instance. `{0}` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.")]
SystemTypeSetAmbiguity(String), SystemTypeSetAmbiguity(String),
/// Systems with conflicting access have indeterminate run order. /// Systems with conflicting access have indeterminate run order.
/// ///
/// This error is disabled by default, but can be opted-in using [`ScheduleBuildSettings`]. /// This error is disabled by default, but can be opted-in using [`ScheduleBuildSettings`].
#[display("Systems with conflicting access have indeterminate run order.\n{_0}")] #[error("Systems with conflicting access have indeterminate run order.\n{0}")]
Ambiguity(String), Ambiguity(String),
/// Tried to run a schedule before all of its systems have been initialized. /// Tried to run a schedule before all of its systems have been initialized.
#[display("Systems in schedule have not been initialized.")] #[error("Systems in schedule have not been initialized.")]
Uninitialized, Uninitialized,
} }
@ -2040,8 +2039,8 @@ impl ScheduleBuildSettings {
/// Error to denote that [`Schedule::initialize`] or [`Schedule::run`] has not yet been called for /// Error to denote that [`Schedule::initialize`] or [`Schedule::run`] has not yet been called for
/// this schedule. /// this schedule.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("executable schedule has not been built")] #[error("executable schedule has not been built")]
pub struct ScheduleNotInitialized; pub struct ScheduleNotInitialized;
#[cfg(test)] #[cfg(test)]

View file

@ -10,7 +10,7 @@ use bevy_utils::{
tracing::{info, warn}, tracing::{info, warn},
TypeIdMap, TypeIdMap,
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[cfg(not(feature = "bevy_debug_stepping"))] #[cfg(not(feature = "bevy_debug_stepping"))]
use bevy_utils::tracing::error; use bevy_utils::tracing::error;
@ -90,8 +90,8 @@ enum Update {
ClearBehavior(InternedScheduleLabel, SystemIdentifier), ClearBehavior(InternedScheduleLabel, SystemIdentifier),
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("not available until all configured schedules have been run; try again next frame")] #[error("not available until all configured schedules have been run; try again next frame")]
pub struct NotReady; pub struct NotReady;
#[derive(Resource, Default)] #[derive(Resource, Default)]

View file

@ -1,6 +1,6 @@
use bevy_utils::tracing::warn; use bevy_utils::tracing::warn;
use core::fmt::Debug; use core::fmt::Debug;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::{ use crate::{
archetype::ArchetypeComponentId, archetype::ArchetypeComponentId,
@ -357,13 +357,12 @@ impl RunSystemOnce for &mut World {
} }
/// Running system failed. /// Running system failed.
#[derive(Error, Display)] #[derive(Error)]
pub enum RunSystemError { pub enum RunSystemError {
/// System could not be run due to parameters that failed validation. /// System could not be run due to parameters that failed validation.
/// ///
/// This can occur because the data required by the system was not present in the world. /// This can occur because the data required by the system was not present in the world.
#[display("The data required by the system {_0:?} was not found in the world and the system did not run due to failed parameter validation.")] #[error("The data required by the system {0:?} was not found in the world and the system did not run due to failed parameter validation.")]
#[error(ignore)]
InvalidParams(Cow<'static, str>), InvalidParams(Cow<'static, str>),
} }

View file

@ -12,7 +12,7 @@ use bevy_ecs_macros::{Component, Resource};
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use core::marker::PhantomData; use core::marker::PhantomData;
use derive_more::derive::{Display, Error}; use thiserror::Error;
/// A small wrapper for [`BoxedSystem`] that also keeps track whether or not the system has been initialized. /// A small wrapper for [`BoxedSystem`] that also keeps track whether or not the system has been initialized.
#[derive(Component)] #[derive(Component)]
@ -613,28 +613,28 @@ where
} }
/// An operation with stored systems failed. /// An operation with stored systems failed.
#[derive(Error, Display)] #[derive(Error)]
pub enum RegisteredSystemError<I: SystemInput = (), O = ()> { pub enum RegisteredSystemError<I: SystemInput = (), O = ()> {
/// A system was run by id, but no system with that id was found. /// A system was run by id, but no system with that id was found.
/// ///
/// Did you forget to register it? /// Did you forget to register it?
#[display("System {_0:?} was not registered")] #[error("System {0:?} was not registered")]
SystemIdNotRegistered(SystemId<I, O>), SystemIdNotRegistered(SystemId<I, O>),
/// A cached system was removed by value, but no system with its type was found. /// A cached system was removed by value, but no system with its type was found.
/// ///
/// Did you forget to register it? /// Did you forget to register it?
#[display("Cached system was not found")] #[error("Cached system was not found")]
SystemNotCached, SystemNotCached,
/// A system tried to run itself recursively. /// A system tried to run itself recursively.
#[display("System {_0:?} tried to run itself recursively")] #[error("System {0:?} tried to run itself recursively")]
Recursive(SystemId<I, O>), Recursive(SystemId<I, O>),
/// A system tried to remove itself. /// A system tried to remove itself.
#[display("System {_0:?} tried to remove itself")] #[error("System {0:?} tried to remove itself")]
SelfRemove(SystemId<I, O>), SelfRemove(SystemId<I, O>),
/// System could not be run due to parameters that failed validation. /// System could not be run due to parameters that failed validation.
/// ///
/// This can occur because the data required by the system was not present in the world. /// This can occur because the data required by the system was not present in the world.
#[display("The data required by the system {_0:?} was not found in the world and the system did not run due to failed parameter validation.")] #[error("The data required by the system {0:?} was not found in the world and the system did not run due to failed parameter validation.")]
InvalidParams(SystemId<I, O>), InvalidParams(SystemId<I, O>),
} }

View file

@ -15,7 +15,7 @@ use crate::{
use bevy_ptr::{OwningPtr, Ptr}; use bevy_ptr::{OwningPtr, Ptr};
use bevy_utils::{HashMap, HashSet}; use bevy_utils::{HashMap, HashSet};
use core::{any::TypeId, marker::PhantomData, mem::MaybeUninit}; use core::{any::TypeId, marker::PhantomData, mem::MaybeUninit};
use derive_more::derive::{Display, Error}; use thiserror::Error;
use super::{unsafe_world_cell::UnsafeEntityCell, Ref, ON_REMOVE, ON_REPLACE}; use super::{unsafe_world_cell::UnsafeEntityCell, Ref, ON_REMOVE, ON_REPLACE};
@ -3019,19 +3019,15 @@ impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a> {
/// Error type returned by [`TryFrom`] conversions from filtered entity types /// Error type returned by [`TryFrom`] conversions from filtered entity types
/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types /// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types
/// ([`EntityRef`]/[`EntityMut`]). /// ([`EntityRef`]/[`EntityMut`]).
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum TryFromFilteredError { pub enum TryFromFilteredError {
/// Error indicating that the filtered entity does not have read access to /// Error indicating that the filtered entity does not have read access to
/// all components. /// all components.
#[display( #[error("Conversion failed, filtered entity ref does not have read access to all components")]
"Conversion failed, filtered entity ref does not have read access to all components"
)]
MissingReadAllAccess, MissingReadAllAccess,
/// Error indicating that the filtered entity does not have write access to /// Error indicating that the filtered entity does not have write access to
/// all components. /// all components.
#[display( #[error("Conversion failed, filtered entity ref does not have write access to all components")]
"Conversion failed, filtered entity ref does not have write access to all components"
)]
MissingWriteAllAccess, MissingWriteAllAccess,
} }

View file

@ -1,39 +1,34 @@
//! Contains error types returned by bevy's schedule. //! Contains error types returned by bevy's schedule.
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::{component::ComponentId, entity::Entity, schedule::InternedScheduleLabel}; use crate::{component::ComponentId, entity::Entity, schedule::InternedScheduleLabel};
/// The error type returned by [`World::try_run_schedule`] if the provided schedule does not exist. /// The error type returned by [`World::try_run_schedule`] if the provided schedule does not exist.
/// ///
/// [`World::try_run_schedule`]: crate::world::World::try_run_schedule /// [`World::try_run_schedule`]: crate::world::World::try_run_schedule
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("The schedule with the label {_0:?} was not found.")] #[error("The schedule with the label {0:?} was not found.")]
#[error(ignore)]
pub struct TryRunScheduleError(pub InternedScheduleLabel); pub struct TryRunScheduleError(pub InternedScheduleLabel);
/// An error that occurs when dynamically retrieving components from an entity. /// An error that occurs when dynamically retrieving components from an entity.
#[derive(Error, Display, Debug, Clone, Copy, PartialEq, Eq)] #[derive(Error, Debug, Clone, Copy, PartialEq, Eq)]
pub enum EntityComponentError { pub enum EntityComponentError {
/// The component with the given [`ComponentId`] does not exist on the entity. /// The component with the given [`ComponentId`] does not exist on the entity.
#[display("The component with ID {_0:?} does not exist on the entity.")] #[error("The component with ID {0:?} does not exist on the entity.")]
#[error(ignore)]
MissingComponent(ComponentId), MissingComponent(ComponentId),
/// The component with the given [`ComponentId`] was requested mutably more than once. /// The component with the given [`ComponentId`] was requested mutably more than once.
#[display("The component with ID {_0:?} was requested mutably more than once.")] #[error("The component with ID {0:?} was requested mutably more than once.")]
#[error(ignore)]
AliasedMutability(ComponentId), AliasedMutability(ComponentId),
} }
/// An error that occurs when fetching entities mutably from a world. /// An error that occurs when fetching entities mutably from a world.
#[derive(Error, Display, Debug, Clone, Copy, PartialEq, Eq)] #[derive(Error, Debug, Clone, Copy, PartialEq, Eq)]
pub enum EntityFetchError { pub enum EntityFetchError {
/// The entity with the given ID does not exist. /// The entity with the given ID does not exist.
#[display("The entity with ID {_0:?} does not exist.")] #[error("The entity with ID {0:?} does not exist.")]
#[error(ignore)]
NoSuchEntity(Entity), NoSuchEntity(Entity),
/// The entity with the given ID was requested mutably more than once. /// The entity with the given ID was requested mutably more than once.
#[display("The entity with ID {_0:?} was requested mutably more than once.")] #[error("The entity with ID {0:?} was requested mutably more than once.")]
#[error(ignore)]
AliasedMutability(Entity), AliasedMutability(Entity),
} }

View file

@ -2,7 +2,7 @@
use core::any::TypeId; use core::any::TypeId;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use bevy_reflect::{Reflect, ReflectFromPtr}; use bevy_reflect::{Reflect, ReflectFromPtr};
@ -198,7 +198,7 @@ impl World {
} }
/// The error type returned by [`World::get_reflect`] and [`World::get_reflect_mut`]. /// The error type returned by [`World::get_reflect`] and [`World::get_reflect_mut`].
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum GetComponentReflectError { pub enum GetComponentReflectError {
/// There is no [`ComponentId`] corresponding to the given [`TypeId`]. /// There is no [`ComponentId`] corresponding to the given [`TypeId`].
/// ///
@ -208,14 +208,11 @@ pub enum GetComponentReflectError {
/// See the documentation for [`bevy_reflect`] for more information. /// See the documentation for [`bevy_reflect`] for more information.
/// ///
/// [`App::register_type`]: ../../../bevy_app/struct.App.html#method.register_type /// [`App::register_type`]: ../../../bevy_app/struct.App.html#method.register_type
#[display( #[error("No `ComponentId` corresponding to {0:?} found (did you call App::register_type()?)")]
"No `ComponentId` corresponding to {_0:?} found (did you call App::register_type()?)"
)]
#[error(ignore)]
NoCorrespondingComponentId(TypeId), NoCorrespondingComponentId(TypeId),
/// The given [`Entity`] does not have a [`Component`] corresponding to the given [`TypeId`]. /// The given [`Entity`] does not have a [`Component`] corresponding to the given [`TypeId`].
#[display("The given `Entity` {entity:?} does not have a `{component_name:?}` component ({component_id:?}, which corresponds to {type_id:?})")] #[error("The given `Entity` {entity:?} does not have a `{component_name:?}` component ({component_id:?}, which corresponds to {type_id:?})")]
EntityDoesNotHaveComponent { EntityDoesNotHaveComponent {
/// The given [`Entity`]. /// The given [`Entity`].
entity: Entity, entity: Entity,
@ -229,7 +226,7 @@ pub enum GetComponentReflectError {
}, },
/// The [`World`] was missing the [`AppTypeRegistry`] resource. /// The [`World`] was missing the [`AppTypeRegistry`] resource.
#[display("The `World` was missing the `AppTypeRegistry` resource")] #[error("The `World` was missing the `AppTypeRegistry` resource")]
MissingAppTypeRegistry, MissingAppTypeRegistry,
/// The [`World`]'s [`TypeRegistry`] did not contain [`TypeData`] for [`ReflectFromPtr`] for the given [`TypeId`]. /// The [`World`]'s [`TypeRegistry`] did not contain [`TypeData`] for [`ReflectFromPtr`] for the given [`TypeId`].
@ -243,8 +240,7 @@ pub enum GetComponentReflectError {
/// [`TypeRegistry`]: bevy_reflect::TypeRegistry /// [`TypeRegistry`]: bevy_reflect::TypeRegistry
/// [`ReflectFromPtr`]: bevy_reflect::ReflectFromPtr /// [`ReflectFromPtr`]: bevy_reflect::ReflectFromPtr
/// [`App::register_type`]: ../../../bevy_app/struct.App.html#method.register_type /// [`App::register_type`]: ../../../bevy_app/struct.App.html#method.register_type
#[display("The `World`'s `TypeRegistry` did not contain `TypeData` for `ReflectFromPtr` for the given {_0:?} (did you call `App::register_type()`?)")] #[error("The `World`'s `TypeRegistry` did not contain `TypeData` for `ReflectFromPtr` for the given {0:?} (did you call `App::register_type()`?)")]
#[error(ignore)]
MissingReflectFromPtrTypeData(TypeId), MissingReflectFromPtrTypeData(TypeId),
} }

View file

@ -21,7 +21,7 @@ use bevy_ptr::Ptr;
#[cfg(feature = "track_change_detection")] #[cfg(feature = "track_change_detection")]
use bevy_ptr::UnsafeCellDeref; use bevy_ptr::UnsafeCellDeref;
use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr}; use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr};
use derive_more::derive::{Display, Error}; use thiserror::Error;
/// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid /// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid
/// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule. /// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule.
@ -1033,14 +1033,17 @@ impl<'w> UnsafeEntityCell<'w> {
} }
/// Error that may be returned when calling [`UnsafeEntityCell::get_mut_by_id`]. /// Error that may be returned when calling [`UnsafeEntityCell::get_mut_by_id`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Error, Display)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
pub enum GetEntityMutByIdError { pub enum GetEntityMutByIdError {
/// The [`ComponentInfo`](crate::component::ComponentInfo) could not be found. /// The [`ComponentInfo`](crate::component::ComponentInfo) could not be found.
#[error("the `ComponentInfo` could not be found")]
InfoNotFound, InfoNotFound,
/// The [`Component`] is immutable. Creating a mutable reference violates its /// The [`Component`] is immutable. Creating a mutable reference violates its
/// invariants. /// invariants.
#[error("the `Component` is immutable")]
ComponentIsImmutable, ComponentIsImmutable,
/// This [`Entity`] does not have the desired [`Component`]. /// This [`Entity`] does not have the desired [`Component`].
#[error("the `Component` could not be found")]
ComponentNotFound, ComponentNotFound,
} }

View file

@ -18,11 +18,7 @@ bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
# other # other
gilrs = "0.11.0" gilrs = "0.11.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
[lints] [lints]
workspace = true workspace = true

View file

@ -10,11 +10,11 @@ use bevy_utils::{
tracing::{debug, warn}, tracing::{debug, warn},
Duration, HashMap, Duration, HashMap,
}; };
use derive_more::derive::{Display, Error, From};
use gilrs::{ use gilrs::{
ff::{self, BaseEffect, BaseEffectType, Repeat, Replay}, ff::{self, BaseEffect, BaseEffectType, Repeat, Replay},
GamepadId, GamepadId,
}; };
use thiserror::Error;
/// A rumble effect that is currently in effect. /// A rumble effect that is currently in effect.
struct RunningRumble { struct RunningRumble {
@ -27,12 +27,12 @@ struct RunningRumble {
effect: SyncCell<ff::Effect>, effect: SyncCell<ff::Effect>,
} }
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
enum RumbleError { enum RumbleError {
#[display("gamepad not found")] #[error("gamepad not found")]
GamepadNotFound, GamepadNotFound,
#[display("gilrs error while rumbling gamepad: {_0}")] #[error("gilrs error while rumbling gamepad: {0}")]
GilrsError(ff::Error), GilrsError(#[from] ff::Error),
} }
/// Contains the gilrs rumble effects that are currently running for each gamepad /// Contains the gilrs rumble effects that are currently running for each gamepad

View file

@ -54,11 +54,7 @@ gltf = { version = "1.4.0", default-features = false, features = [
"names", "names",
"utils", "utils",
] } ] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
base64 = "0.22.0" base64 = "0.22.0"
percent-encoding = "2.1" percent-encoding = "2.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }

View file

@ -45,7 +45,6 @@ use bevy_utils::{
tracing::{error, info_span, warn}, tracing::{error, info_span, warn},
HashMap, HashSet, HashMap, HashSet,
}; };
use derive_more::derive::{Display, Error, From};
use gltf::{ use gltf::{
accessor::Iter, accessor::Iter,
image::Source, image::Source,
@ -60,6 +59,7 @@ use std::{
io::Error, io::Error,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use thiserror::Error;
#[cfg(feature = "bevy_animation")] #[cfg(feature = "bevy_animation")]
use { use {
bevy_animation::{prelude::*, AnimationTarget, AnimationTargetId}, bevy_animation::{prelude::*, AnimationTarget, AnimationTargetId},
@ -67,59 +67,56 @@ use {
}; };
/// An error that occurs when loading a glTF file. /// An error that occurs when loading a glTF file.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum GltfError { pub enum GltfError {
/// Unsupported primitive mode. /// Unsupported primitive mode.
#[display("unsupported primitive mode")] #[error("unsupported primitive mode")]
UnsupportedPrimitive { UnsupportedPrimitive {
/// The primitive mode. /// The primitive mode.
mode: Mode, mode: Mode,
}, },
/// Invalid glTF file. /// Invalid glTF file.
#[display("invalid glTF file: {_0}")] #[error("invalid glTF file: {0}")]
Gltf(gltf::Error), Gltf(#[from] gltf::Error),
/// Binary blob is missing. /// Binary blob is missing.
#[display("binary blob is missing")] #[error("binary blob is missing")]
MissingBlob, MissingBlob,
/// Decoding the base64 mesh data failed. /// Decoding the base64 mesh data failed.
#[display("failed to decode base64 mesh data")] #[error("failed to decode base64 mesh data")]
Base64Decode(base64::DecodeError), Base64Decode(#[from] base64::DecodeError),
/// Unsupported buffer format. /// Unsupported buffer format.
#[display("unsupported buffer format")] #[error("unsupported buffer format")]
BufferFormatUnsupported, BufferFormatUnsupported,
/// Invalid image mime type. /// Invalid image mime type.
#[display("invalid image mime type: {_0}")] #[error("invalid image mime type: {0}")]
#[error(ignore)]
#[from(ignore)] #[from(ignore)]
InvalidImageMimeType(String), InvalidImageMimeType(String),
/// Error when loading a texture. Might be due to a disabled image file format feature. /// Error when loading a texture. Might be due to a disabled image file format feature.
#[display("You may need to add the feature for the file format: {_0}")] #[error("You may need to add the feature for the file format: {0}")]
ImageError(TextureError), ImageError(#[from] TextureError),
/// Failed to read bytes from an asset path. /// Failed to read bytes from an asset path.
#[display("failed to read bytes from an asset path: {_0}")] #[error("failed to read bytes from an asset path: {0}")]
ReadAssetBytesError(ReadAssetBytesError), ReadAssetBytesError(#[from] ReadAssetBytesError),
/// Failed to load asset from an asset path. /// Failed to load asset from an asset path.
#[display("failed to load asset from an asset path: {_0}")] #[error("failed to load asset from an asset path: {0}")]
AssetLoadError(AssetLoadError), AssetLoadError(#[from] AssetLoadError),
/// Missing sampler for an animation. /// Missing sampler for an animation.
#[display("Missing sampler for animation {_0}")] #[error("Missing sampler for animation {0}")]
#[error(ignore)]
#[from(ignore)] #[from(ignore)]
MissingAnimationSampler(usize), MissingAnimationSampler(usize),
/// Failed to generate tangents. /// Failed to generate tangents.
#[display("failed to generate tangents: {_0}")] #[error("failed to generate tangents: {0}")]
GenerateTangentsError(bevy_render::mesh::GenerateTangentsError), GenerateTangentsError(#[from] bevy_render::mesh::GenerateTangentsError),
/// Failed to generate morph targets. /// Failed to generate morph targets.
#[display("failed to generate morph targets: {_0}")] #[error("failed to generate morph targets: {0}")]
MorphTarget(bevy_render::mesh::morph::MorphBuildError), MorphTarget(#[from] bevy_render::mesh::morph::MorphBuildError),
/// Circular children in Nodes /// Circular children in Nodes
#[display("GLTF model must be a tree, found cycle instead at node indices: {_0:?}")] #[error("GLTF model must be a tree, found cycle instead at node indices: {0:?}")]
#[error(ignore)]
#[from(ignore)] #[from(ignore)]
CircularChildren(String), CircularChildren(String),
/// Failed to load a file. /// Failed to load a file.
#[display("failed to load file: {_0}")] #[error("failed to load file: {0}")]
Io(Error), Io(#[from] Error),
} }
/// Loads glTF files with all of their data as their corresponding bevy representations. /// Loads glTF files with all of their data as their corresponding bevy representations.

View file

@ -4,11 +4,11 @@ use bevy_render::{
render_resource::VertexFormat, render_resource::VertexFormat,
}; };
use bevy_utils::HashMap; use bevy_utils::HashMap;
use derive_more::derive::{Display, Error};
use gltf::{ use gltf::{
accessor::{DataType, Dimensions}, accessor::{DataType, Dimensions},
mesh::util::{ReadColors, ReadJoints, ReadTexCoords, ReadWeights}, mesh::util::{ReadColors, ReadJoints, ReadTexCoords, ReadWeights},
}; };
use thiserror::Error;
/// Represents whether integer data requires normalization /// Represents whether integer data requires normalization
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -30,11 +30,11 @@ impl Normalization {
} }
/// An error that occurs when accessing buffer data /// An error that occurs when accessing buffer data
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub(crate) enum AccessFailed { pub(crate) enum AccessFailed {
#[display("Malformed vertex attribute data")] #[error("Malformed vertex attribute data")]
MalformedData, MalformedData,
#[display("Unsupported vertex attribute format")] #[error("Unsupported vertex attribute format")]
UnsupportedFormat, UnsupportedFormat,
} }
@ -241,16 +241,13 @@ enum ConversionMode {
TexCoord, TexCoord,
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[error(ignore)]
pub(crate) enum ConvertAttributeError { pub(crate) enum ConvertAttributeError {
#[display( #[error("Vertex attribute {0} has format {1:?} but expected {3:?} for target attribute {2}")]
"Vertex attribute {_0} has format {_1:?} but expected {_3:?} for target attribute {_2}"
)]
WrongFormat(String, VertexFormat, String, VertexFormat), WrongFormat(String, VertexFormat, String, VertexFormat),
#[display("{_0} in accessor {_1}")] #[error("{0} in accessor {1}")]
AccessFailed(AccessFailed, usize), AccessFailed(AccessFailed, usize),
#[display("Unknown vertex attribute {_0}")] #[error("Unknown vertex attribute {0}")]
UnknownName(String), UnknownName(String),
} }

View file

@ -53,11 +53,7 @@ wgpu-types = { version = "23", default-features = false }
# TODO: remove dependency on wgpu once https://github.com/gfx-rs/wgpu/pull/6648, 6649 and 6650 have been released # TODO: remove dependency on wgpu once https://github.com/gfx-rs/wgpu/pull/6648, 6649 and 6650 have been released
wgpu = { version = "23.0.1", default-features = false } wgpu = { version = "23.0.1", default-features = false }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
futures-lite = "2.0.1" futures-lite = "2.0.1"
ddsfile = { version = "0.5.2", optional = true } ddsfile = { version = "0.5.2", optional = true }
ktx2 = { version = "0.3.0", optional = true } ktx2 = { version = "0.3.0", optional = true }

View file

@ -1,15 +1,16 @@
use crate::{Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings}; use crate::{Image, ImageFormat, ImageFormatSetting, ImageLoader, ImageLoaderSettings};
use bevy_asset::saver::{AssetSaver, SavedAsset}; use bevy_asset::saver::{AssetSaver, SavedAsset};
use derive_more::derive::{Display, Error, From};
use futures_lite::AsyncWriteExt; use futures_lite::AsyncWriteExt;
use thiserror::Error;
pub struct CompressedImageSaver; pub struct CompressedImageSaver;
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum CompressedImageSaverError { pub enum CompressedImageSaverError {
Io(std::io::Error), #[error(transparent)]
Io(#[from] std::io::Error),
} }
impl AssetSaver for CompressedImageSaver { impl AssetSaver for CompressedImageSaver {

View file

@ -1,8 +1,8 @@
use crate::{Image, TextureFormatPixelInfo}; use crate::{Image, TextureFormatPixelInfo};
use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages}; use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};
use derive_more::derive::{Display, Error, From};
use image::ImageDecoder; use image::ImageDecoder;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error;
use wgpu_types::{Extent3d, TextureDimension, TextureFormat}; use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
/// Loads EXR textures as Texture assets /// Loads EXR textures as Texture assets
@ -18,11 +18,13 @@ pub struct ExrTextureLoaderSettings {
/// Possible errors that can be produced by [`ExrTextureLoader`] /// Possible errors that can be produced by [`ExrTextureLoader`]
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
#[cfg(feature = "exr")] #[cfg(feature = "exr")]
pub enum ExrTextureLoaderError { pub enum ExrTextureLoaderError {
Io(std::io::Error), #[error(transparent)]
ImageError(image::ImageError), Io(#[from] std::io::Error),
#[error(transparent)]
ImageError(#[from] image::ImageError),
} }
impl AssetLoader for ExrTextureLoader { impl AssetLoader for ExrTextureLoader {

View file

@ -1,9 +1,9 @@
use crate::{Image, TextureFormatPixelInfo}; use crate::{Image, TextureFormatPixelInfo};
use bevy_asset::RenderAssetUsages; use bevy_asset::RenderAssetUsages;
use bevy_asset::{io::Reader, AssetLoader, LoadContext}; use bevy_asset::{io::Reader, AssetLoader, LoadContext};
use derive_more::derive::{Display, Error, From};
use image::DynamicImage; use image::DynamicImage;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error;
use wgpu_types::{Extent3d, TextureDimension, TextureFormat}; use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
/// Loads HDR textures as Texture assets /// Loads HDR textures as Texture assets
@ -16,12 +16,12 @@ pub struct HdrTextureLoaderSettings {
} }
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum HdrTextureLoaderError { pub enum HdrTextureLoaderError {
#[display("Could load texture: {_0}")] #[error("Could load texture: {0}")]
Io(std::io::Error), Io(#[from] std::io::Error),
#[display("Could not extract image: {_0}")] #[error("Could not extract image: {0}")]
Image(image::ImageError), Image(#[from] image::ImageError),
} }
impl AssetLoader for HdrTextureLoader { impl AssetLoader for HdrTextureLoader {

View file

@ -11,8 +11,8 @@ use bevy_math::{AspectRatio, UVec2, UVec3, Vec2};
use bevy_reflect::std_traits::ReflectDefault; use bevy_reflect::std_traits::ReflectDefault;
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use core::hash::Hash; use core::hash::Hash;
use derive_more::derive::{Display, Error, From};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error;
use wgpu::{SamplerDescriptor, TextureViewDescriptor}; use wgpu::{SamplerDescriptor, TextureViewDescriptor};
use wgpu_types::{ use wgpu_types::{
AddressMode, CompareFunction, Extent3d, Features, FilterMode, SamplerBorderColor, AddressMode, CompareFunction, Extent3d, Features, FilterMode, SamplerBorderColor,
@ -1393,48 +1393,39 @@ pub enum TranscodeFormat {
} }
/// An error that occurs when accessing specific pixels in a texture /// An error that occurs when accessing specific pixels in a texture
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum TextureAccessError { pub enum TextureAccessError {
#[display("out of bounds (x: {x}, y: {y}, z: {z})")] #[error("out of bounds (x: {x}, y: {y}, z: {z})")]
OutOfBounds { x: u32, y: u32, z: u32 }, OutOfBounds { x: u32, y: u32, z: u32 },
#[display("unsupported texture format: {_0:?}")] #[error("unsupported texture format: {0:?}")]
#[error(ignore)]
UnsupportedTextureFormat(TextureFormat), UnsupportedTextureFormat(TextureFormat),
#[display("attempt to access texture with different dimension")] #[error("attempt to access texture with different dimension")]
WrongDimension, WrongDimension,
} }
/// An error that occurs when loading a texture /// An error that occurs when loading a texture
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
#[error(ignore)]
pub enum TextureError { pub enum TextureError {
#[display("invalid image mime type: {_0}")] #[error("invalid image mime type: {0}")]
#[from(ignore)]
InvalidImageMimeType(String), InvalidImageMimeType(String),
#[display("invalid image extension: {_0}")] #[error("invalid image extension: {0}")]
#[from(ignore)]
InvalidImageExtension(String), InvalidImageExtension(String),
#[display("failed to load an image: {_0}")] #[error("failed to load an image: {0}")]
ImageError(image::ImageError), ImageError(#[from] image::ImageError),
#[display("unsupported texture format: {_0}")] #[error("unsupported texture format: {0}")]
#[from(ignore)]
UnsupportedTextureFormat(String), UnsupportedTextureFormat(String),
#[display("supercompression not supported: {_0}")] #[error("supercompression not supported: {0}")]
#[from(ignore)]
SuperCompressionNotSupported(String), SuperCompressionNotSupported(String),
#[display("failed to load an image: {_0}")] #[error("failed to load an image: {0}")]
#[from(ignore)]
SuperDecompressionError(String), SuperDecompressionError(String),
#[display("invalid data: {_0}")] #[error("invalid data: {0}")]
#[from(ignore)]
InvalidData(String), InvalidData(String),
#[display("transcode error: {_0}")] #[error("transcode error: {0}")]
#[from(ignore)]
TranscodeError(String), TranscodeError(String),
#[display("format requires transcoding: {_0:?}")] #[error("format requires transcoding: {0:?}")]
FormatRequiresTranscodingError(TranscodeFormat), FormatRequiresTranscodingError(TranscodeFormat),
/// Only cubemaps with six faces are supported. /// Only cubemaps with six faces are supported.
#[display("only cubemaps with six faces are supported")] #[error("only cubemaps with six faces are supported")]
IncompleteCubemap, IncompleteCubemap,
} }

View file

@ -1,6 +1,6 @@
use crate::image::{Image, ImageFormat, ImageType, TextureError}; use crate::image::{Image, ImageFormat, ImageType, TextureError};
use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages}; use bevy_asset::{io::Reader, AssetLoader, LoadContext, RenderAssetUsages};
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
use super::{CompressedImageFormats, ImageSampler}; use super::{CompressedImageFormats, ImageSampler};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -109,12 +109,12 @@ impl Default for ImageLoaderSettings {
} }
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum ImageLoaderError { pub enum ImageLoaderError {
#[display("Could load shader: {_0}")] #[error("Could load shader: {0}")]
Io(std::io::Error), Io(#[from] std::io::Error),
#[display("Could not load texture file: {_0}")] #[error("Could not load texture file: {0}")]
FileTexture(FileTextureError), FileTexture(#[from] FileTextureError),
} }
impl AssetLoader for ImageLoader { impl AssetLoader for ImageLoader {
@ -171,8 +171,8 @@ impl AssetLoader for ImageLoader {
} }
/// An error that occurs when loading a texture from a file. /// An error that occurs when loading a texture from a file.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("Error reading image file {path}: {error}, this is an error in `bevy_render`.")] #[error("Error reading image file {path}: {error}, this is an error in `bevy_render`.")]
pub struct FileTextureError { pub struct FileTextureError {
error: TextureError, error: TextureError,
path: String, path: String,

View file

@ -1,7 +1,7 @@
use crate::{Image, TextureFormatPixelInfo}; use crate::{Image, TextureFormatPixelInfo};
use bevy_asset::RenderAssetUsages; use bevy_asset::RenderAssetUsages;
use derive_more::derive::{Display, Error};
use image::{DynamicImage, ImageBuffer}; use image::{DynamicImage, ImageBuffer};
use thiserror::Error;
use wgpu_types::{Extent3d, TextureDimension, TextureFormat}; use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
impl Image { impl Image {
@ -204,16 +204,14 @@ impl Image {
/// Errors that occur while converting an [`Image`] into a [`DynamicImage`] /// Errors that occur while converting an [`Image`] into a [`DynamicImage`]
#[non_exhaustive] #[non_exhaustive]
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum IntoDynamicImageError { pub enum IntoDynamicImageError {
/// Conversion into dynamic image not supported for source format. /// Conversion into dynamic image not supported for source format.
#[display("Conversion into dynamic image not supported for {_0:?}.")] #[error("Conversion into dynamic image not supported for {0:?}.")]
#[error(ignore)]
UnsupportedFormat(TextureFormat), UnsupportedFormat(TextureFormat),
/// Encountered an unknown error during conversion. /// Encountered an unknown error during conversion.
#[display("Failed to convert into {_0:?}.")] #[error("Failed to convert into {0:?}.")]
#[error(ignore)]
UnknownConversionError(TextureFormat), UnknownConversionError(TextureFormat),
} }

View file

@ -37,11 +37,8 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
# other # other
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
smol_str = "0.2" smol_str = "0.2"
[lints] [lints]

View file

@ -19,7 +19,8 @@ use bevy_utils::{
tracing::{info, warn}, tracing::{info, warn},
Duration, HashMap, Duration, HashMap,
}; };
use derive_more::derive::{Display, Error, From}; use derive_more::derive::From;
use thiserror::Error;
/// A gamepad event. /// A gamepad event.
/// ///
@ -247,26 +248,22 @@ impl GamepadAxisChangedEvent {
} }
/// Errors that occur when setting axis settings for gamepad input. /// Errors that occur when setting axis settings for gamepad input.
#[derive(Error, Display, Debug, PartialEq)] #[derive(Error, Debug, PartialEq)]
pub enum AxisSettingsError { pub enum AxisSettingsError {
/// The given parameter `livezone_lowerbound` was not in range -1.0..=0.0. /// The given parameter `livezone_lowerbound` was not in range -1.0..=0.0.
#[display("invalid livezone_lowerbound {_0}, expected value [-1.0..=0.0]")] #[error("invalid livezone_lowerbound {0}, expected value [-1.0..=0.0]")]
#[error(ignore)]
LiveZoneLowerBoundOutOfRange(f32), LiveZoneLowerBoundOutOfRange(f32),
/// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0. /// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0.
#[display("invalid deadzone_lowerbound {_0}, expected value [-1.0..=0.0]")] #[error("invalid deadzone_lowerbound {0}, expected value [-1.0..=0.0]")]
#[error(ignore)]
DeadZoneLowerBoundOutOfRange(f32), DeadZoneLowerBoundOutOfRange(f32),
/// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0. /// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0.
#[display("invalid deadzone_upperbound {_0}, expected value [0.0..=1.0]")] #[error("invalid deadzone_upperbound {0}, expected value [0.0..=1.0]")]
#[error(ignore)]
DeadZoneUpperBoundOutOfRange(f32), DeadZoneUpperBoundOutOfRange(f32),
/// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0. /// The given parameter `deadzone_lowerbound` was not in range -1.0..=0.0.
#[display("invalid livezone_upperbound {_0}, expected value [0.0..=1.0]")] #[error("invalid livezone_upperbound {0}, expected value [0.0..=1.0]")]
#[error(ignore)]
LiveZoneUpperBoundOutOfRange(f32), LiveZoneUpperBoundOutOfRange(f32),
/// Parameter `livezone_lowerbound` was not less than or equal to parameter `deadzone_lowerbound`. /// Parameter `livezone_lowerbound` was not less than or equal to parameter `deadzone_lowerbound`.
#[display("invalid parameter values livezone_lowerbound {} deadzone_lowerbound {}, expected livezone_lowerbound <= deadzone_lowerbound", livezone_lowerbound, deadzone_lowerbound)] #[error("invalid parameter values livezone_lowerbound {} deadzone_lowerbound {}, expected livezone_lowerbound <= deadzone_lowerbound", livezone_lowerbound, deadzone_lowerbound)]
LiveZoneLowerBoundGreaterThanDeadZoneLowerBound { LiveZoneLowerBoundGreaterThanDeadZoneLowerBound {
/// The value of the `livezone_lowerbound` parameter. /// The value of the `livezone_lowerbound` parameter.
livezone_lowerbound: f32, livezone_lowerbound: f32,
@ -274,7 +271,7 @@ pub enum AxisSettingsError {
deadzone_lowerbound: f32, deadzone_lowerbound: f32,
}, },
/// Parameter `deadzone_upperbound` was not less than or equal to parameter `livezone_upperbound`. /// Parameter `deadzone_upperbound` was not less than or equal to parameter `livezone_upperbound`.
#[display("invalid parameter values livezone_upperbound {} deadzone_upperbound {}, expected deadzone_upperbound <= livezone_upperbound", livezone_upperbound, deadzone_upperbound)] #[error("invalid parameter values livezone_upperbound {} deadzone_upperbound {}, expected deadzone_upperbound <= livezone_upperbound", livezone_upperbound, deadzone_upperbound)]
DeadZoneUpperBoundGreaterThanLiveZoneUpperBound { DeadZoneUpperBoundGreaterThanLiveZoneUpperBound {
/// The value of the `livezone_upperbound` parameter. /// The value of the `livezone_upperbound` parameter.
livezone_upperbound: f32, livezone_upperbound: f32,
@ -282,24 +279,21 @@ pub enum AxisSettingsError {
deadzone_upperbound: f32, deadzone_upperbound: f32,
}, },
/// The given parameter was not in range 0.0..=2.0. /// The given parameter was not in range 0.0..=2.0.
#[display("invalid threshold {_0}, expected 0.0 <= threshold <= 2.0")] #[error("invalid threshold {0}, expected 0.0 <= threshold <= 2.0")]
#[error(ignore)]
Threshold(f32), Threshold(f32),
} }
/// Errors that occur when setting button settings for gamepad input. /// Errors that occur when setting button settings for gamepad input.
#[derive(Error, Display, Debug, PartialEq)] #[derive(Error, Debug, PartialEq)]
pub enum ButtonSettingsError { pub enum ButtonSettingsError {
/// The given parameter was not in range 0.0..=1.0. /// The given parameter was not in range 0.0..=1.0.
#[display("invalid release_threshold {_0}, expected value [0.0..=1.0]")] #[error("invalid release_threshold {0}, expected value [0.0..=1.0]")]
#[error(ignore)]
ReleaseThresholdOutOfRange(f32), ReleaseThresholdOutOfRange(f32),
/// The given parameter was not in range 0.0..=1.0. /// The given parameter was not in range 0.0..=1.0.
#[display("invalid press_threshold {_0}, expected [0.0..=1.0]")] #[error("invalid press_threshold {0}, expected [0.0..=1.0]")]
#[error(ignore)]
PressThresholdOutOfRange(f32), PressThresholdOutOfRange(f32),
/// Parameter `release_threshold` was not less than or equal to `press_threshold`. /// Parameter `release_threshold` was not less than or equal to `press_threshold`.
#[display("invalid parameter values release_threshold {} press_threshold {}, expected release_threshold <= press_threshold", release_threshold, press_threshold)] #[error("invalid parameter values release_threshold {} press_threshold {}, expected release_threshold <= press_threshold", release_threshold, press_threshold)]
ReleaseThresholdGreaterThanPressThreshold { ReleaseThresholdGreaterThanPressThreshold {
/// The value of the `press_threshold` parameter. /// The value of the `press_threshold` parameter.
press_threshold: f32, press_threshold: f32,

View file

@ -11,10 +11,9 @@ rust-version = "1.81.0"
[dependencies] [dependencies]
glam = { version = "0.29", default-features = false, features = ["bytemuck"] } glam = { version = "0.29", default-features = false, features = ["bytemuck"] }
thiserror = { version = "2", default-features = false }
derive_more = { version = "1", default-features = false, features = [ derive_more = { version = "1", default-features = false, features = [
"error",
"from", "from",
"display",
"into", "into",
] } ] }
itertools = { version = "0.13.0", default-features = false } itertools = { version = "0.13.0", default-features = false }

View file

@ -1,7 +1,8 @@
//! Provides a simple aspect ratio struct to help with calculations. //! Provides a simple aspect ratio struct to help with calculations.
use crate::Vec2; use crate::Vec2;
use derive_more::derive::{Display, Error, Into}; use derive_more::derive::Into;
use thiserror::Error;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
@ -84,15 +85,15 @@ impl TryFrom<Vec2> for AspectRatio {
} }
/// An Error type for when [`super::AspectRatio`] is provided invalid width or height values /// An Error type for when [`super::AspectRatio`] is provided invalid width or height values
#[derive(Error, Display, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Error, Debug, PartialEq, Eq, Clone, Copy)]
pub enum AspectRatioError { pub enum AspectRatioError {
/// Error due to width or height having zero as a value. /// Error due to width or height having zero as a value.
#[display("AspectRatio error: width or height is zero")] #[error("AspectRatio error: width or height is zero")]
Zero, Zero,
/// Error due towidth or height being infinite. /// Error due towidth or height being infinite.
#[display("AspectRatio error: width or height is infinite")] #[error("AspectRatio error: width or height is infinite")]
Infinite, Infinite,
/// Error due to width or height being Not a Number (NaN). /// Error due to width or height being Not a Number (NaN).
#[display("AspectRatio error: width or height is NaN")] #[error("AspectRatio error: width or height is NaN")]
NaN, NaN,
} }

View file

@ -7,7 +7,7 @@ use crate::{
Vec2, VectorSpace, Vec2, VectorSpace,
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use {alloc::vec, alloc::vec::Vec, core::iter::once, itertools::Itertools}; use {alloc::vec, alloc::vec::Vec, core::iter::once, itertools::Itertools};
@ -102,8 +102,8 @@ impl<P: VectorSpace> CubicGenerator<P> for CubicBezier<P> {
/// An error returned during cubic curve generation for cubic Bezier curves indicating that a /// An error returned during cubic curve generation for cubic Bezier curves indicating that a
/// segment of control points was not present. /// segment of control points was not present.
#[derive(Clone, Debug, Error, Display)] #[derive(Clone, Debug, Error)]
#[display("Unable to generate cubic curve: at least one set of control points is required")] #[error("Unable to generate cubic curve: at least one set of control points is required")]
pub struct CubicBezierError; pub struct CubicBezierError;
/// A spline interpolated continuously between the nearest two control points, with the position and /// A spline interpolated continuously between the nearest two control points, with the position and
@ -527,10 +527,10 @@ impl<P: VectorSpace> CyclicCubicGenerator<P> for CubicBSpline<P> {
} }
/// Error during construction of [`CubicNurbs`] /// Error during construction of [`CubicNurbs`]
#[derive(Clone, Debug, Error, Display)] #[derive(Clone, Debug, Error)]
pub enum CubicNurbsError { pub enum CubicNurbsError {
/// Provided the wrong number of knots. /// Provided the wrong number of knots.
#[display("Wrong number of knots: expected {expected}, provided {provided}")] #[error("Wrong number of knots: expected {expected}, provided {provided}")]
KnotsNumberMismatch { KnotsNumberMismatch {
/// Expected number of knots /// Expected number of knots
expected: usize, expected: usize,
@ -539,13 +539,13 @@ pub enum CubicNurbsError {
}, },
/// The provided knots had a descending knot pair. Subsequent knots must /// The provided knots had a descending knot pair. Subsequent knots must
/// either increase or stay the same. /// either increase or stay the same.
#[display("Invalid knots: contains descending knot pair")] #[error("Invalid knots: contains descending knot pair")]
DescendingKnots, DescendingKnots,
/// The provided knots were all equal. Knots must contain at least one increasing pair. /// The provided knots were all equal. Knots must contain at least one increasing pair.
#[display("Invalid knots: all knots are equal")] #[error("Invalid knots: all knots are equal")]
ConstantKnots, ConstantKnots,
/// Provided a different number of weights and control points. /// Provided a different number of weights and control points.
#[display("Incorrect number of weights: expected {expected}, provided {provided}")] #[error("Incorrect number of weights: expected {expected}, provided {provided}")]
WeightsNumberMismatch { WeightsNumberMismatch {
/// Expected number of weights /// Expected number of weights
expected: usize, expected: usize,
@ -553,7 +553,7 @@ pub enum CubicNurbsError {
provided: usize, provided: usize,
}, },
/// The number of control points provided is less than 4. /// The number of control points provided is less than 4.
#[display("Not enough control points, at least 4 are required, {provided} were provided")] #[error("Not enough control points, at least 4 are required, {provided} were provided")]
NotEnoughControlPoints { NotEnoughControlPoints {
/// The number of control points provided /// The number of control points provided
provided: usize, provided: usize,
@ -909,8 +909,8 @@ impl<P: VectorSpace> CyclicCubicGenerator<P> for LinearSpline<P> {
} }
/// An error indicating that a spline construction didn't have enough control points to generate a curve. /// An error indicating that a spline construction didn't have enough control points to generate a curve.
#[derive(Clone, Debug, Error, Display)] #[derive(Clone, Debug, Error)]
#[display("Not enough data to build curve: needed at least {expected} control points but was only given {given}")] #[error("Not enough data to build curve: needed at least {expected} control points but was only given {given}")]
pub struct InsufficientDataError { pub struct InsufficientDataError {
expected: usize, expected: usize,
given: usize, given: usize,

View file

@ -10,7 +10,7 @@ use crate::ops;
use super::interval::Interval; use super::interval::Interval;
use core::fmt::Debug; use core::fmt::Debug;
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use {alloc::vec::Vec, itertools::Itertools}; use {alloc::vec::Vec, itertools::Itertools};
@ -136,18 +136,18 @@ pub struct EvenCore<T> {
} }
/// An error indicating that an [`EvenCore`] could not be constructed. /// An error indicating that an [`EvenCore`] could not be constructed.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not construct an EvenCore")] #[error("Could not construct an EvenCore")]
pub enum EvenCoreError { pub enum EvenCoreError {
/// Not enough samples were provided. /// Not enough samples were provided.
#[display("Need at least two samples to create an EvenCore, but {samples} were provided")] #[error("Need at least two samples to create an EvenCore, but {samples} were provided")]
NotEnoughSamples { NotEnoughSamples {
/// The number of samples that were provided. /// The number of samples that were provided.
samples: usize, samples: usize,
}, },
/// Unbounded domains are not compatible with `EvenCore`. /// Unbounded domains are not compatible with `EvenCore`.
#[display("Cannot create a EvenCore over an unbounded domain")] #[error("Cannot create a EvenCore over an unbounded domain")]
UnboundedDomain, UnboundedDomain,
} }
@ -340,11 +340,11 @@ pub struct UnevenCore<T> {
} }
/// An error indicating that an [`UnevenCore`] could not be constructed. /// An error indicating that an [`UnevenCore`] could not be constructed.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not construct an UnevenCore")] #[error("Could not construct an UnevenCore")]
pub enum UnevenCoreError { pub enum UnevenCoreError {
/// Not enough samples were provided. /// Not enough samples were provided.
#[display( #[error(
"Need at least two unique samples to create an UnevenCore, but {samples} were provided" "Need at least two unique samples to create an UnevenCore, but {samples} were provided"
)] )]
NotEnoughSamples { NotEnoughSamples {
@ -481,15 +481,15 @@ pub struct ChunkedUnevenCore<T> {
} }
/// An error that indicates that a [`ChunkedUnevenCore`] could not be formed. /// An error that indicates that a [`ChunkedUnevenCore`] could not be formed.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not create a ChunkedUnevenCore")] #[error("Could not create a ChunkedUnevenCore")]
pub enum ChunkedUnevenCoreError { pub enum ChunkedUnevenCoreError {
/// The width of a `ChunkedUnevenCore` cannot be zero. /// The width of a `ChunkedUnevenCore` cannot be zero.
#[display("Chunk width must be at least 1")] #[error("Chunk width must be at least 1")]
ZeroWidth, ZeroWidth,
/// At least two sample times are necessary to interpolate in `ChunkedUnevenCore`. /// At least two sample times are necessary to interpolate in `ChunkedUnevenCore`.
#[display( #[error(
"Need at least two unique samples to create a ChunkedUnevenCore, but {samples} were provided" "Need at least two unique samples to create a ChunkedUnevenCore, but {samples} were provided"
)] )]
NotEnoughSamples { NotEnoughSamples {
@ -498,7 +498,7 @@ pub enum ChunkedUnevenCoreError {
}, },
/// The length of the value buffer is supposed to be the `width` times the number of samples. /// The length of the value buffer is supposed to be the `width` times the number of samples.
#[display("Expected {expected} total values based on width, but {actual} were provided")] #[error("Expected {expected} total values based on width, but {actual} were provided")]
MismatchedLengths { MismatchedLengths {
/// The expected length of the value buffer. /// The expected length of the value buffer.
expected: usize, expected: usize,
@ -507,7 +507,7 @@ pub enum ChunkedUnevenCoreError {
}, },
/// Tried to infer the width, but the ratio of lengths wasn't an integer, so no such length exists. /// Tried to infer the width, but the ratio of lengths wasn't an integer, so no such length exists.
#[display("The length of the list of values ({values_len}) was not divisible by that of the list of times ({times_len})")] #[error("The length of the list of values ({values_len}) was not divisible by that of the list of times ({times_len})")]
NonDivisibleLengths { NonDivisibleLengths {
/// The length of the value buffer. /// The length of the value buffer.
values_len: usize, values_len: usize,

View file

@ -4,8 +4,8 @@ use core::{
cmp::{max_by, min_by}, cmp::{max_by, min_by},
ops::RangeInclusive, ops::RangeInclusive,
}; };
use derive_more::derive::{Display, Error};
use itertools::Either; use itertools::Either;
use thiserror::Error;
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
@ -29,26 +29,26 @@ pub struct Interval {
} }
/// An error that indicates that an operation would have returned an invalid [`Interval`]. /// An error that indicates that an operation would have returned an invalid [`Interval`].
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("The resulting interval would be invalid (empty or with a NaN endpoint)")] #[error("The resulting interval would be invalid (empty or with a NaN endpoint)")]
pub struct InvalidIntervalError; pub struct InvalidIntervalError;
/// An error indicating that spaced points could not be extracted from an unbounded interval. /// An error indicating that spaced points could not be extracted from an unbounded interval.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Cannot extract spaced points from an unbounded interval")] #[error("Cannot extract spaced points from an unbounded interval")]
pub struct SpacedPointsError; pub struct SpacedPointsError;
/// An error indicating that a linear map between intervals could not be constructed because of /// An error indicating that a linear map between intervals could not be constructed because of
/// unboundedness. /// unboundedness.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not construct linear function to map between intervals")] #[error("Could not construct linear function to map between intervals")]
pub(super) enum LinearMapError { pub(super) enum LinearMapError {
/// The source interval being mapped out of was unbounded. /// The source interval being mapped out of was unbounded.
#[display("The source interval is unbounded")] #[error("The source interval is unbounded")]
SourceUnbounded, SourceUnbounded,
/// The target interval being mapped into was unbounded. /// The target interval being mapped into was unbounded.
#[display("The target interval is unbounded")] #[error("The target interval is unbounded")]
TargetUnbounded, TargetUnbounded,
} }

View file

@ -309,8 +309,8 @@ pub use {
use crate::VectorSpace; use crate::VectorSpace;
use core::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData, ops::Deref};
use derive_more::derive::{Display, Error};
use interval::InvalidIntervalError; use interval::InvalidIntervalError;
use thiserror::Error;
/// A trait for a type that can represent values of type `T` parametrized over a fixed interval. /// A trait for a type that can represent values of type `T` parametrized over a fixed interval.
/// ///
@ -915,74 +915,73 @@ where
/// An error indicating that a linear reparameterization couldn't be performed because of /// An error indicating that a linear reparameterization couldn't be performed because of
/// malformed inputs. /// malformed inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not build a linear function to reparametrize this curve")] #[error("Could not build a linear function to reparametrize this curve")]
pub enum LinearReparamError { pub enum LinearReparamError {
/// The source curve that was to be reparametrized had unbounded domain. /// The source curve that was to be reparametrized had unbounded domain.
#[display("This curve has unbounded domain")] #[error("This curve has unbounded domain")]
SourceCurveUnbounded, SourceCurveUnbounded,
/// The target interval for reparameterization was unbounded. /// The target interval for reparameterization was unbounded.
#[display("The target interval for reparameterization is unbounded")] #[error("The target interval for reparameterization is unbounded")]
TargetIntervalUnbounded, TargetIntervalUnbounded,
} }
/// An error indicating that a reversion of a curve couldn't be performed because of /// An error indicating that a reversion of a curve couldn't be performed because of
/// malformed inputs. /// malformed inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not reverse this curve")] #[error("Could not reverse this curve")]
pub enum ReverseError { pub enum ReverseError {
/// The source curve that was to be reversed had unbounded domain end. /// The source curve that was to be reversed had unbounded domain end.
#[display("This curve has an unbounded domain end")] #[error("This curve has an unbounded domain end")]
SourceDomainEndInfinite, SourceDomainEndInfinite,
} }
/// An error indicating that a repetition of a curve couldn't be performed because of malformed /// An error indicating that a repetition of a curve couldn't be performed because of malformed
/// inputs. /// inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not repeat this curve")] #[error("Could not repeat this curve")]
pub enum RepeatError { pub enum RepeatError {
/// The source curve that was to be repeated had unbounded domain. /// The source curve that was to be repeated had unbounded domain.
#[display("This curve has an unbounded domain")] #[error("This curve has an unbounded domain")]
SourceDomainUnbounded, SourceDomainUnbounded,
} }
/// An error indicating that a ping ponging of a curve couldn't be performed because of /// An error indicating that a ping ponging of a curve couldn't be performed because of
/// malformed inputs. /// malformed inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not ping pong this curve")] #[error("Could not ping pong this curve")]
pub enum PingPongError { pub enum PingPongError {
/// The source curve that was to be ping ponged had unbounded domain end. /// The source curve that was to be ping ponged had unbounded domain end.
#[display("This curve has an unbounded domain end")] #[error("This curve has an unbounded domain end")]
SourceDomainEndInfinite, SourceDomainEndInfinite,
} }
/// An error indicating that an end-to-end composition couldn't be performed because of /// An error indicating that an end-to-end composition couldn't be performed because of
/// malformed inputs. /// malformed inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not compose these curves together")] #[error("Could not compose these curves together")]
pub enum ChainError { pub enum ChainError {
/// The right endpoint of the first curve was infinite. /// The right endpoint of the first curve was infinite.
#[display("The first curve's domain has an infinite end")] #[error("The first curve's domain has an infinite end")]
FirstEndInfinite, FirstEndInfinite,
/// The left endpoint of the second curve was infinite. /// The left endpoint of the second curve was infinite.
#[display("The second curve's domain has an infinite start")] #[error("The second curve's domain has an infinite start")]
SecondStartInfinite, SecondStartInfinite,
} }
/// An error indicating that a resampling operation could not be performed because of /// An error indicating that a resampling operation could not be performed because of
/// malformed inputs. /// malformed inputs.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("Could not resample from this curve because of bad inputs")] #[error("Could not resample from this curve because of bad inputs")]
pub enum ResamplingError { pub enum ResamplingError {
/// This resampling operation was not provided with enough samples to have well-formed output. /// This resampling operation was not provided with enough samples to have well-formed output.
#[display("Not enough unique samples to construct resampled curve")] #[error("Not enough unique samples to construct resampled curve")]
#[error(ignore)]
NotEnoughSamples(usize), NotEnoughSamples(usize),
/// This resampling operation failed because of an unbounded interval. /// This resampling operation failed because of an unbounded interval.
#[display("Could not resample because this curve has unbounded domain")] #[error("Could not resample because this curve has unbounded domain")]
UnboundedDomain, UnboundedDomain,
} }

View file

@ -1,5 +1,6 @@
use core::f32::consts::{FRAC_1_SQRT_2, FRAC_PI_2, FRAC_PI_3, PI}; use core::f32::consts::{FRAC_1_SQRT_2, FRAC_PI_2, FRAC_PI_3, PI};
use derive_more::derive::{Display, Error, From}; use derive_more::derive::From;
use thiserror::Error;
use super::{Measured2d, Primitive2d, WindingOrder}; use super::{Measured2d, Primitive2d, WindingOrder};
use crate::{ use crate::{
@ -1654,10 +1655,10 @@ pub struct ConvexPolygon<const N: usize> {
impl<const N: usize> Primitive2d for ConvexPolygon<N> {} impl<const N: usize> Primitive2d for ConvexPolygon<N> {}
/// An error that happens when creating a [`ConvexPolygon`]. /// An error that happens when creating a [`ConvexPolygon`].
#[derive(Error, Display, Debug, Clone)] #[derive(Error, Debug, Clone)]
pub enum ConvexPolygonError { pub enum ConvexPolygonError {
/// The created polygon is not convex. /// The created polygon is not convex.
#[display("The created polygon is not convex")] #[error("The created polygon is not convex")]
Concave, Concave,
} }

View file

@ -27,11 +27,7 @@ bytemuck = { version = "1.5" }
wgpu-types = { version = "23", default-features = false } wgpu-types = { version = "23", default-features = false }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
hexasphere = "15.0" hexasphere = "15.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
[lints] [lints]
workspace = true workspace = true

View file

@ -26,10 +26,10 @@
use super::VertexAttributeValues; use super::VertexAttributeValues;
use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4}; use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[derive(Debug, Clone, Error, Display)] #[derive(Debug, Clone, Error)]
#[display("cannot convert VertexAttributeValues::{variant} to {into}")] #[error("cannot convert VertexAttributeValues::{variant} to {into}")]
pub struct FromVertexAttributeError { pub struct FromVertexAttributeError {
from: VertexAttributeValues, from: VertexAttributeValues,
variant: &'static str, variant: &'static str,

View file

@ -1,7 +1,7 @@
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use core::iter; use core::iter;
use core::iter::FusedIterator; use core::iter::FusedIterator;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use wgpu_types::IndexFormat; use wgpu_types::IndexFormat;
/// A disjunction of four iterators. This is necessary to have a well-formed type for the output /// A disjunction of four iterators. This is necessary to have a well-formed type for the output
@ -34,35 +34,35 @@ where
} }
/// An error that occurred while trying to invert the winding of a [`Mesh`](super::Mesh). /// An error that occurred while trying to invert the winding of a [`Mesh`](super::Mesh).
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum MeshWindingInvertError { pub enum MeshWindingInvertError {
/// This error occurs when you try to invert the winding for a mesh with [`PrimitiveTopology::PointList`](super::PrimitiveTopology::PointList). /// This error occurs when you try to invert the winding for a mesh with [`PrimitiveTopology::PointList`](super::PrimitiveTopology::PointList).
#[display("Mesh winding invertation does not work for primitive topology `PointList`")] #[error("Mesh winding invertation does not work for primitive topology `PointList`")]
WrongTopology, WrongTopology,
/// This error occurs when you try to invert the winding for a mesh with /// This error occurs when you try to invert the winding for a mesh with
/// * [`PrimitiveTopology::TriangleList`](super::PrimitiveTopology::TriangleList), but the indices are not in chunks of 3. /// * [`PrimitiveTopology::TriangleList`](super::PrimitiveTopology::TriangleList), but the indices are not in chunks of 3.
/// * [`PrimitiveTopology::LineList`](super::PrimitiveTopology::LineList), but the indices are not in chunks of 2. /// * [`PrimitiveTopology::LineList`](super::PrimitiveTopology::LineList), but the indices are not in chunks of 2.
#[display("Indices weren't in chunks according to topology")] #[error("Indices weren't in chunks according to topology")]
AbruptIndicesEnd, AbruptIndicesEnd,
} }
/// An error that occurred while trying to extract a collection of triangles from a [`Mesh`](super::Mesh). /// An error that occurred while trying to extract a collection of triangles from a [`Mesh`](super::Mesh).
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum MeshTrianglesError { pub enum MeshTrianglesError {
#[display("Source mesh does not have primitive topology TriangleList or TriangleStrip")] #[error("Source mesh does not have primitive topology TriangleList or TriangleStrip")]
WrongTopology, WrongTopology,
#[display("Source mesh lacks position data")] #[error("Source mesh lacks position data")]
MissingPositions, MissingPositions,
#[display("Source mesh position data is not Float32x3")] #[error("Source mesh position data is not Float32x3")]
PositionsFormat, PositionsFormat,
#[display("Source mesh lacks face index data")] #[error("Source mesh lacks face index data")]
MissingIndices, MissingIndices,
#[display("Face index data references vertices that do not exist")] #[error("Face index data references vertices that do not exist")]
BadIndices, BadIndices,
} }

View file

@ -1,6 +1,6 @@
use super::{Indices, Mesh, VertexAttributeValues}; use super::{Indices, Mesh, VertexAttributeValues};
use bevy_math::Vec3; use bevy_math::Vec3;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use wgpu_types::{PrimitiveTopology, VertexFormat}; use wgpu_types::{PrimitiveTopology, VertexFormat};
struct MikktspaceGeometryHelper<'a> { struct MikktspaceGeometryHelper<'a> {
@ -53,21 +53,18 @@ impl bevy_mikktspace::Geometry for MikktspaceGeometryHelper<'_> {
} }
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
/// Failed to generate tangents for the mesh. /// Failed to generate tangents for the mesh.
pub enum GenerateTangentsError { pub enum GenerateTangentsError {
#[display("cannot generate tangents for {_0:?}")] #[error("cannot generate tangents for {0:?}")]
#[error(ignore)]
UnsupportedTopology(PrimitiveTopology), UnsupportedTopology(PrimitiveTopology),
#[display("missing indices")] #[error("missing indices")]
MissingIndices, MissingIndices,
#[display("missing vertex attributes '{_0}'")] #[error("missing vertex attributes '{0}'")]
#[error(ignore)]
MissingVertexAttribute(&'static str), MissingVertexAttribute(&'static str),
#[display("the '{_0}' vertex attribute should have {_1:?} format")] #[error("the '{0}' vertex attribute should have {1:?} format")]
#[error(ignore)]
InvalidVertexAttributeFormat(&'static str, VertexFormat), InvalidVertexAttributeFormat(&'static str, VertexFormat),
#[display("mesh not suitable for tangent generation")] #[error("mesh not suitable for tangent generation")]
MikktspaceError, MikktspaceError,
} }

View file

@ -6,7 +6,7 @@ use bevy_math::Vec3;
use bevy_reflect::prelude::*; use bevy_reflect::prelude::*;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use core::iter; use core::iter;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use wgpu_types::{Extent3d, TextureDimension, TextureFormat}; use wgpu_types::{Extent3d, TextureDimension, TextureFormat};
const MAX_TEXTURE_WIDTH: u32 = 2048; const MAX_TEXTURE_WIDTH: u32 = 2048;
@ -17,9 +17,9 @@ const MAX_COMPONENTS: u32 = MAX_TEXTURE_WIDTH * MAX_TEXTURE_WIDTH;
/// Max target count available for [morph targets](MorphWeights). /// Max target count available for [morph targets](MorphWeights).
pub const MAX_MORPH_WEIGHTS: usize = 64; pub const MAX_MORPH_WEIGHTS: usize = 64;
#[derive(Error, Display, Clone, Debug)] #[derive(Error, Clone, Debug)]
pub enum MorphBuildError { pub enum MorphBuildError {
#[display( #[error(
"Too many vertex×components in morph target, max is {MAX_COMPONENTS}, \ "Too many vertex×components in morph target, max is {MAX_COMPONENTS}, \
got {vertex_count}×{component_count} = {}", got {vertex_count}×{component_count} = {}",
*vertex_count * *component_count as usize *vertex_count * *component_count as usize
@ -28,7 +28,7 @@ pub enum MorphBuildError {
vertex_count: usize, vertex_count: usize,
component_count: u32, component_count: u32,
}, },
#[display( #[error(
"Bevy only supports up to {} morph targets (individual poses), tried to \ "Bevy only supports up to {} morph targets (individual poses), tried to \
create a model with {target_count} morph targets", create a model with {target_count} morph targets",
MAX_MORPH_WEIGHTS MAX_MORPH_WEIGHTS

View file

@ -2,14 +2,14 @@ use crate::{Indices, Mesh, MeshBuilder, Meshable, PrimitiveTopology};
use bevy_asset::RenderAssetUsages; use bevy_asset::RenderAssetUsages;
use bevy_math::{ops, primitives::Sphere}; use bevy_math::{ops, primitives::Sphere};
use core::f32::consts::PI; use core::f32::consts::PI;
use derive_more::derive::{Display, Error};
use hexasphere::shapes::IcoSphere; use hexasphere::shapes::IcoSphere;
use thiserror::Error;
/// An error when creating an icosphere [`Mesh`] from a [`SphereMeshBuilder`]. /// An error when creating an icosphere [`Mesh`] from a [`SphereMeshBuilder`].
#[derive(Clone, Copy, Debug, Error, Display)] #[derive(Clone, Copy, Debug, Error)]
pub enum IcosphereError { pub enum IcosphereError {
/// The icosphere has too many vertices. /// The icosphere has too many vertices.
#[display("Cannot create an icosphere of {subdivisions} subdivisions due to there being too many vertices being generated: {number_of_resulting_points}. (Limited to 65535 vertices or 79 subdivisions)")] #[error("Cannot create an icosphere of {subdivisions} subdivisions due to there being too many vertices being generated: {number_of_resulting_points}. (Limited to 65535 vertices or 79 subdivisions)")]
TooManyVertices { TooManyVertices {
/// The number of subdivisions used. 79 is the largest allowed value for a mesh to be generated. /// The number of subdivisions used. 79 is the largest allowed value for a mesh to be generated.
subdivisions: u32, subdivisions: u32,

View file

@ -5,7 +5,7 @@ use bevy_math::Vec3;
use bevy_utils::HashSet; use bevy_utils::HashSet;
use bytemuck::cast_slice; use bytemuck::cast_slice;
use core::hash::{Hash, Hasher}; use core::hash::{Hash, Hasher};
use derive_more::derive::{Display, Error}; use thiserror::Error;
use wgpu_types::{BufferAddress, VertexAttribute, VertexFormat, VertexStepMode}; use wgpu_types::{BufferAddress, VertexAttribute, VertexFormat, VertexStepMode};
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -108,8 +108,8 @@ impl MeshVertexBufferLayout {
} }
} }
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
#[display("Mesh is missing requested attribute: {name} ({id:?}, pipeline type: {pipeline_type:?})")] #[error("Mesh is missing requested attribute: {name} ({id:?}, pipeline type: {pipeline_type:?})")]
pub struct MissingVertexAttributeError { pub struct MissingVertexAttributeError {
pub pipeline_type: Option<&'static str>, pub pipeline_type: Option<&'static str>,
id: MeshVertexAttributeId, id: MeshVertexAttributeId,

View file

@ -52,11 +52,8 @@ bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }
# other # other
bitflags = "2.3" bitflags = "2.3"
fixedbitset = "0.5" fixedbitset = "0.5"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
# meshlet # meshlet
lz4_flex = { version = "0.11", default-features = false, features = [ lz4_flex = { version = "0.11", default-features = false, features = [
"frame", "frame",

View file

@ -8,10 +8,10 @@ use bevy_math::{Vec2, Vec3};
use bevy_reflect::TypePath; use bevy_reflect::TypePath;
use bevy_tasks::block_on; use bevy_tasks::block_on;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use derive_more::derive::{Display, Error, From};
use half::f16; use half::f16;
use lz4_flex::frame::{FrameDecoder, FrameEncoder}; use lz4_flex::frame::{FrameDecoder, FrameEncoder};
use std::io::{Read, Write}; use std::io::{Read, Write};
use thiserror::Error;
/// Unique identifier for the [`MeshletMesh`] asset format. /// Unique identifier for the [`MeshletMesh`] asset format.
const MESHLET_MESH_ASSET_MAGIC: u64 = 1717551717668; const MESHLET_MESH_ASSET_MAGIC: u64 = 1717551717668;
@ -211,16 +211,16 @@ impl AssetLoader for MeshletMeshLoader {
} }
} }
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum MeshletMeshSaveOrLoadError { pub enum MeshletMeshSaveOrLoadError {
#[display("file was not a MeshletMesh asset")] #[error("file was not a MeshletMesh asset")]
WrongFileType, WrongFileType,
#[display("expected asset version {MESHLET_MESH_ASSET_VERSION} but found version {found}")] #[error("expected asset version {MESHLET_MESH_ASSET_VERSION} but found version {found}")]
WrongVersion { found: u64 }, WrongVersion { found: u64 },
#[display("failed to compress or decompress asset data")] #[error("failed to compress or decompress asset data")]
CompressionOrDecompression(lz4_flex::frame::Error), CompressionOrDecompression(#[from] lz4_flex::frame::Error),
#[display("failed to read or write asset data")] #[error("failed to read or write asset data")]
Io(std::io::Error), Io(#[from] std::io::Error),
} }
async fn async_read_u64(reader: &mut dyn Reader) -> Result<u64, std::io::Error> { async fn async_read_u64(reader: &mut dyn Reader) -> Result<u64, std::io::Error> {

View file

@ -10,7 +10,6 @@ use bevy_render::{
use bevy_utils::HashMap; use bevy_utils::HashMap;
use bitvec::{order::Lsb0, vec::BitVec, view::BitView}; use bitvec::{order::Lsb0, vec::BitVec, view::BitView};
use core::iter; use core::iter;
use derive_more::derive::{Display, Error};
use half::f16; use half::f16;
use itertools::Itertools; use itertools::Itertools;
use meshopt::{ use meshopt::{
@ -19,6 +18,7 @@ use meshopt::{
}; };
use metis::Graph; use metis::Graph;
use smallvec::SmallVec; use smallvec::SmallVec;
use thiserror::Error;
// Aim to have 8 meshlets per group // Aim to have 8 meshlets per group
const TARGET_MESHLETS_PER_GROUP: usize = 8; const TARGET_MESHLETS_PER_GROUP: usize = 8;
@ -615,12 +615,12 @@ fn pack2x16snorm(v: Vec2) -> u32 {
} }
/// An error produced by [`MeshletMesh::from_mesh`]. /// An error produced by [`MeshletMesh::from_mesh`].
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum MeshToMeshletMeshConversionError { pub enum MeshToMeshletMeshConversionError {
#[display("Mesh primitive topology is not TriangleList")] #[error("Mesh primitive topology is not TriangleList")]
WrongMeshPrimitiveTopology, WrongMeshPrimitiveTopology,
#[display("Mesh attributes are not {{POSITION, NORMAL, UV_0}}")] #[error("Mesh attributes are not {{POSITION, NORMAL, UV_0}}")]
WrongMeshVertexAttributes, WrongMeshVertexAttributes,
#[display("Mesh has no indices")] #[error("Mesh has no indices")]
MeshMissingIndices, MeshMissingIndices,
} }

View file

@ -51,11 +51,8 @@ erased-serde = { version = "0.4", default-features = false, features = [
] } ] }
disqualified = { version = "1.0", default-features = false } disqualified = { version = "1.0", default-features = false }
downcast-rs = { version = "1.2", default-features = false } downcast-rs = { version = "1.2", default-features = false }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
serde = { version = "1", default-features = false, features = ["alloc"] } serde = { version = "1", default-features = false, features = ["alloc"] }
spin = { version = "0.9.8", default-features = false, features = [ spin = { version = "0.9.8", default-features = false, features = [
"once", "once",

View file

@ -6,7 +6,7 @@ use alloc::boxed::Box;
use alloc::sync::Arc; use alloc::sync::Arc;
use bevy_utils::HashMap; use bevy_utils::HashMap;
use core::slice::Iter; use core::slice::Iter;
use derive_more::derive::{Display, Error}; use thiserror::Error;
/// Describes the form of an enum variant. /// Describes the form of an enum variant.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@ -40,12 +40,12 @@ pub enum VariantType {
} }
/// A [`VariantInfo`]-specific error. /// A [`VariantInfo`]-specific error.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum VariantInfoError { pub enum VariantInfoError {
/// Caused when a variant was expected to be of a certain [type], but was not. /// Caused when a variant was expected to be of a certain [type], but was not.
/// ///
/// [type]: VariantType /// [type]: VariantType
#[display("variant type mismatch: expected {expected:?}, received {received:?}")] #[error("variant type mismatch: expected {expected:?}, received {received:?}")]
TypeMismatch { TypeMismatch {
expected: VariantType, expected: VariantType,
received: VariantType, received: VariantType,

View file

@ -1,6 +1,6 @@
use alloc::borrow::Cow; use alloc::borrow::Cow;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::func::args::Ownership; use crate::func::args::Ownership;
@ -10,19 +10,17 @@ use alloc::{boxed::Box, format, vec};
/// An error that occurs when converting an [argument]. /// An error that occurs when converting an [argument].
/// ///
/// [argument]: crate::func::args::Arg /// [argument]: crate::func::args::Arg
#[derive(Debug, Error, Display, PartialEq)] #[derive(Debug, Error, PartialEq)]
pub enum ArgError { pub enum ArgError {
/// The argument is not the expected type. /// The argument is not the expected type.
#[display("expected `{expected}` but received `{received}` (@ argument index {index})")] #[error("expected `{expected}` but received `{received}` (@ argument index {index})")]
UnexpectedType { UnexpectedType {
index: usize, index: usize,
expected: Cow<'static, str>, expected: Cow<'static, str>,
received: Cow<'static, str>, received: Cow<'static, str>,
}, },
/// The argument has the wrong ownership. /// The argument has the wrong ownership.
#[display( #[error("expected {expected} value but received {received} value (@ argument index {index})")]
"expected {expected} value but received {received} value (@ argument index {index})"
)]
InvalidOwnership { InvalidOwnership {
index: usize, index: usize,
expected: Ownership, expected: Ownership,
@ -31,6 +29,6 @@ pub enum ArgError {
/// Occurs when attempting to access an argument from an empty [`ArgList`]. /// Occurs when attempting to access an argument from an empty [`ArgList`].
/// ///
/// [`ArgList`]: crate::func::args::ArgList /// [`ArgList`]: crate::func::args::ArgList
#[display("expected an argument but received none")] #[error("expected an argument but received none")]
EmptyArgList, EmptyArgList,
} }

View file

@ -1,6 +1,6 @@
use crate::func::{args::ArgError, Return}; use crate::func::{args::ArgError, Return};
use alloc::borrow::Cow; use alloc::borrow::Cow;
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use alloc::{boxed::Box, format, vec}; use alloc::{boxed::Box, format, vec};
@ -9,12 +9,13 @@ use alloc::{boxed::Box, format, vec};
/// ///
/// [`DynamicFunction`]: crate::func::DynamicFunction /// [`DynamicFunction`]: crate::func::DynamicFunction
/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut /// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
#[derive(Debug, Error, Display, PartialEq, From)] #[derive(Debug, Error, PartialEq)]
pub enum FunctionError { pub enum FunctionError {
/// An error occurred while converting an argument. /// An error occurred while converting an argument.
ArgError(ArgError), #[error(transparent)]
ArgError(#[from] ArgError),
/// The number of arguments provided does not match the expected number. /// The number of arguments provided does not match the expected number.
#[display("expected {expected} arguments but received {received}")] #[error("expected {expected} arguments but received {received}")]
ArgCountMismatch { expected: usize, received: usize }, ArgCountMismatch { expected: usize, received: usize },
} }
@ -30,15 +31,14 @@ pub type FunctionResult<'a> = Result<Return<'a>, FunctionError>;
/// An error that occurs when registering a function into a [`FunctionRegistry`]. /// An error that occurs when registering a function into a [`FunctionRegistry`].
/// ///
/// [`FunctionRegistry`]: crate::func::FunctionRegistry /// [`FunctionRegistry`]: crate::func::FunctionRegistry
#[derive(Debug, Error, Display, PartialEq)] #[derive(Debug, Error, PartialEq)]
pub enum FunctionRegistrationError { pub enum FunctionRegistrationError {
/// A function with the given name has already been registered. /// A function with the given name has already been registered.
/// ///
/// Contains the duplicate function name. /// Contains the duplicate function name.
#[display("a function has already been registered with name {_0:?}")] #[error("a function has already been registered with name {0:?}")]
#[error(ignore)]
DuplicateName(Cow<'static, str>), DuplicateName(Cow<'static, str>),
/// The function is missing a name by which it can be registered. /// The function is missing a name by which it can be registered.
#[display("function name is missing")] #[error("function name is missing")]
MissingName, MissingName,
} }

View file

@ -1,5 +1,5 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[cfg(feature = "functions")] #[cfg(feature = "functions")]
use crate::func::Function; use crate::func::Function;
@ -131,8 +131,8 @@ macro_rules! impl_reflect_kind_conversions {
/// Caused when a type was expected to be of a certain [kind], but was not. /// Caused when a type was expected to be of a certain [kind], but was not.
/// ///
/// [kind]: ReflectKind /// [kind]: ReflectKind
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
#[display("kind mismatch: expected {expected:?}, received {received:?}")] #[error("kind mismatch: expected {expected:?}, received {received:?}")]
pub struct ReflectKindMismatchError { pub struct ReflectKindMismatchError {
pub expected: ReflectKind, pub expected: ReflectKind,
pub received: ReflectKind, pub received: ReflectKind,

View file

@ -11,23 +11,25 @@ use parse::PathParser;
use crate::{PartialReflect, Reflect}; use crate::{PartialReflect, Reflect};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::fmt; use core::fmt;
use derive_more::derive::{Display, From}; use derive_more::derive::From;
use thiserror::Error;
type PathResult<'a, T> = Result<T, ReflectPathError<'a>>; type PathResult<'a, T> = Result<T, ReflectPathError<'a>>;
/// An error returned from a failed path string query. /// An error returned from a failed path string query.
#[derive(Debug, PartialEq, Eq, Display, From)] #[derive(Error, Debug, PartialEq, Eq)]
pub enum ReflectPathError<'a> { pub enum ReflectPathError<'a> {
/// An error caused by trying to access a path that's not able to be accessed, /// An error caused by trying to access a path that's not able to be accessed,
/// see [`AccessError`] for details. /// see [`AccessError`] for details.
#[error(transparent)]
InvalidAccess(AccessError<'a>), InvalidAccess(AccessError<'a>),
/// An error that occurs when a type cannot downcast to a given type. /// An error that occurs when a type cannot downcast to a given type.
#[display("Can't downcast result of access to the given type")] #[error("Can't downcast result of access to the given type")]
InvalidDowncast, InvalidDowncast,
/// An error caused by an invalid path string that couldn't be parsed. /// An error caused by an invalid path string that couldn't be parsed.
#[display("Encountered an error at offset {offset} while parsing `{path}`: {error}")] #[error("Encountered an error at offset {offset} while parsing `{path}`: {error}")]
ParseError { ParseError {
/// Position in `path`. /// Position in `path`.
offset: usize, offset: usize,
@ -38,7 +40,11 @@ pub enum ReflectPathError<'a> {
}, },
} }
impl<'a> core::error::Error for ReflectPathError<'a> {} impl<'a> From<AccessError<'a>> for ReflectPathError<'a> {
fn from(value: AccessError<'a>) -> Self {
ReflectPathError::InvalidAccess(value)
}
}
/// Something that can be interpreted as a reflection path in [`GetPath`]. /// Something that can be interpreted as a reflection path in [`GetPath`].
pub trait ReflectPath<'a>: Sized { pub trait ReflectPath<'a>: Sized {

View file

@ -3,39 +3,34 @@ use core::{
num::ParseIntError, num::ParseIntError,
str::from_utf8_unchecked, str::from_utf8_unchecked,
}; };
use thiserror::Error;
use derive_more::derive::{Display, Error, From};
use super::{Access, ReflectPathError}; use super::{Access, ReflectPathError};
/// An error that occurs when parsing reflect path strings. /// An error that occurs when parsing reflect path strings.
#[derive(Debug, PartialEq, Eq, Error, Display)] #[derive(Debug, PartialEq, Eq, Error)]
#[error(ignore)] #[error(transparent)]
pub struct ParseError<'a>(Error<'a>); pub struct ParseError<'a>(Error<'a>);
/// A parse error for a path string. /// A parse error for a path string.
#[derive(Debug, PartialEq, Eq, Error, Display, From)] #[derive(Debug, PartialEq, Eq, Error)]
enum Error<'a> { enum Error<'a> {
#[display("expected an identifier, but reached end of path string")] #[error("expected an identifier, but reached end of path string")]
NoIdent, NoIdent,
#[display("expected an identifier, got '{_0}' instead")] #[error("expected an identifier, got '{0}' instead")]
#[error(ignore)]
#[from(ignore)]
ExpectedIdent(Token<'a>), ExpectedIdent(Token<'a>),
#[display("failed to parse index as integer")] #[error("failed to parse index as integer")]
InvalidIndex(ParseIntError), InvalidIndex(#[from] ParseIntError),
#[display("a '[' wasn't closed, reached end of path string before finding a ']'")] #[error("a '[' wasn't closed, reached end of path string before finding a ']'")]
Unclosed, Unclosed,
#[display("a '[' wasn't closed properly, got '{_0}' instead")] #[error("a '[' wasn't closed properly, got '{0}' instead")]
#[error(ignore)]
#[from(ignore)]
BadClose(Token<'a>), BadClose(Token<'a>),
#[display("a ']' was found before an opening '['")] #[error("a ']' was found before an opening '['")]
CloseBeforeOpen, CloseBeforeOpen,
} }

View file

@ -9,39 +9,39 @@ use core::{
fmt::Debug, fmt::Debug,
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::utility::NonGenericTypeInfoCell; use crate::utility::NonGenericTypeInfoCell;
/// A enumeration of all error outcomes that might happen when running [`try_apply`](PartialReflect::try_apply). /// A enumeration of all error outcomes that might happen when running [`try_apply`](PartialReflect::try_apply).
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum ApplyError { pub enum ApplyError {
#[display("attempted to apply `{from_kind}` to `{to_kind}`")] #[error("attempted to apply `{from_kind}` to `{to_kind}`")]
/// Attempted to apply the wrong [kind](ReflectKind) to a type, e.g. a struct to a enum. /// Attempted to apply the wrong [kind](ReflectKind) to a type, e.g. a struct to a enum.
MismatchedKinds { MismatchedKinds {
from_kind: ReflectKind, from_kind: ReflectKind,
to_kind: ReflectKind, to_kind: ReflectKind,
}, },
#[display("enum variant `{variant_name}` doesn't have a field named `{field_name}`")] #[error("enum variant `{variant_name}` doesn't have a field named `{field_name}`")]
/// Enum variant that we tried to apply to was missing a field. /// Enum variant that we tried to apply to was missing a field.
MissingEnumField { MissingEnumField {
variant_name: Box<str>, variant_name: Box<str>,
field_name: Box<str>, field_name: Box<str>,
}, },
#[display("`{from_type}` is not `{to_type}`")] #[error("`{from_type}` is not `{to_type}`")]
/// Tried to apply incompatible types. /// Tried to apply incompatible types.
MismatchedTypes { MismatchedTypes {
from_type: Box<str>, from_type: Box<str>,
to_type: Box<str>, to_type: Box<str>,
}, },
#[display("attempted to apply type with {from_size} size to a type with {to_size} size")] #[error("attempted to apply type with {from_size} size to a type with {to_size} size")]
/// Attempted to apply to types with mismatched sizez, e.g. a [u8; 4] to [u8; 3]. /// Attempted to apply to types with mismatched sizez, e.g. a [u8; 4] to [u8; 3].
DifferentSize { from_size: usize, to_size: usize }, DifferentSize { from_size: usize, to_size: usize },
#[display("variant with name `{variant_name}` does not exist on enum `{enum_name}`")] #[error("variant with name `{variant_name}` does not exist on enum `{enum_name}`")]
/// The enum we tried to apply to didn't contain a variant with the give name. /// The enum we tried to apply to didn't contain a variant with the give name.
UnknownVariant { UnknownVariant {
enum_name: Box<str>, enum_name: Box<str>,

View file

@ -8,7 +8,7 @@ use core::{
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
hash::Hash, hash::Hash,
}; };
use derive_more::derive::{Display, Error}; use thiserror::Error;
/// A static accessor to compile-time type information. /// A static accessor to compile-time type information.
/// ///
@ -163,12 +163,12 @@ impl<T: Typed> DynamicTyped for T {
} }
/// A [`TypeInfo`]-specific error. /// A [`TypeInfo`]-specific error.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum TypeInfoError { pub enum TypeInfoError {
/// Caused when a type was expected to be of a certain [kind], but was not. /// Caused when a type was expected to be of a certain [kind], but was not.
/// ///
/// [kind]: ReflectKind /// [kind]: ReflectKind
#[display("kind mismatch: expected {expected:?}, received {received:?}")] #[error("kind mismatch: expected {expected:?}, received {received:?}")]
KindMismatch { KindMismatch {
expected: ReflectKind, expected: ReflectKind,
received: ReflectKind, received: ReflectKind,

View file

@ -79,11 +79,8 @@ naga = { version = "23", features = ["wgsl-in"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
bytemuck = { version = "1.5", features = ["derive", "must_cast"] } bytemuck = { version = "1.5", features = ["derive", "must_cast"] }
downcast-rs = "1.2.0" downcast-rs = "1.2.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
futures-lite = "2.0.1" futures-lite = "2.0.1"
ktx2 = { version = "0.3.0", optional = true } ktx2 = { version = "0.3.0", optional = true }
encase = { version = "0.10", features = ["glam"] } encase = { version = "0.10", features = ["glam"] }

View file

@ -16,13 +16,13 @@ use bevy_utils::{
HashMap, HashSet, HashMap, HashSet,
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum PrepareAssetError<E: Send + Sync + 'static> { pub enum PrepareAssetError<E: Send + Sync + 'static> {
#[display("Failed to prepare asset")] #[error("Failed to prepare asset")]
RetryNextUpdate(E), RetryNextUpdate(E),
#[display("Failed to build bind group: {_0}")] #[error("Failed to build bind group: {0}")]
AsBindGroupError(AsBindGroupError), AsBindGroupError(AsBindGroupError),
} }

View file

@ -4,7 +4,7 @@ use crate::{
}; };
use alloc::borrow::Cow; use alloc::borrow::Cow;
use bevy_ecs::entity::Entity; use bevy_ecs::entity::Entity;
use derive_more::derive::{Display, Error}; use thiserror::Error;
use super::{InternedRenderSubGraph, RenderSubGraph}; use super::{InternedRenderSubGraph, RenderSubGraph};
@ -231,21 +231,19 @@ impl<'a> RenderGraphContext<'a> {
} }
} }
#[derive(Error, Display, Debug, Eq, PartialEq)] #[derive(Error, Debug, Eq, PartialEq)]
pub enum RunSubGraphError { pub enum RunSubGraphError {
#[display("attempted to run sub-graph `{_0:?}`, but it does not exist")] #[error("attempted to run sub-graph `{0:?}`, but it does not exist")]
#[error(ignore)]
MissingSubGraph(InternedRenderSubGraph), MissingSubGraph(InternedRenderSubGraph),
#[display("attempted to pass inputs to sub-graph `{_0:?}`, which has no input slots")] #[error("attempted to pass inputs to sub-graph `{0:?}`, which has no input slots")]
#[error(ignore)]
SubGraphHasNoInputs(InternedRenderSubGraph), SubGraphHasNoInputs(InternedRenderSubGraph),
#[display("sub graph (name: `{graph_name:?}`) could not be run because slot `{slot_name}` at index {slot_index} has no value")] #[error("sub graph (name: `{graph_name:?}`) could not be run because slot `{slot_name}` at index {slot_index} has no value")]
MissingInput { MissingInput {
slot_index: usize, slot_index: usize,
slot_name: Cow<'static, str>, slot_name: Cow<'static, str>,
graph_name: InternedRenderSubGraph, graph_name: InternedRenderSubGraph,
}, },
#[display("attempted to use the wrong type for input slot")] #[error("attempted to use the wrong type for input slot")]
MismatchedInputSlotType { MismatchedInputSlotType {
graph_name: InternedRenderSubGraph, graph_name: InternedRenderSubGraph,
slot_index: usize, slot_index: usize,
@ -255,12 +253,11 @@ pub enum RunSubGraphError {
}, },
} }
#[derive(Error, Display, Debug, Eq, PartialEq)] #[derive(Error, Debug, Eq, PartialEq)]
pub enum OutputSlotError { pub enum OutputSlotError {
#[display("output slot `{_0:?}` does not exist")] #[error("output slot `{0:?}` does not exist")]
#[error(ignore)]
InvalidSlot(SlotLabel), InvalidSlot(SlotLabel),
#[display("attempted to output a value of type `{actual}` to output slot `{label:?}`, which has type `{expected}`")] #[error("attempted to output a value of type `{actual}` to output slot `{label:?}`, which has type `{expected}`")]
MismatchedSlotType { MismatchedSlotType {
label: SlotLabel, label: SlotLabel,
expected: SlotType, expected: SlotType,
@ -268,12 +265,11 @@ pub enum OutputSlotError {
}, },
} }
#[derive(Error, Display, Debug, Eq, PartialEq)] #[derive(Error, Debug, Eq, PartialEq)]
pub enum InputSlotError { pub enum InputSlotError {
#[display("input slot `{_0:?}` does not exist")] #[error("input slot `{0:?}` does not exist")]
#[error(ignore)]
InvalidSlot(SlotLabel), InvalidSlot(SlotLabel),
#[display("attempted to retrieve a value of type `{actual}` from input slot `{label:?}`, which has type `{expected}`")] #[error("attempted to retrieve a value of type `{actual}` from input slot `{label:?}`, which has type `{expected}`")]
MismatchedSlotType { MismatchedSlotType {
label: SlotLabel, label: SlotLabel,
expected: SlotType, expected: SlotType,

View file

@ -12,45 +12,40 @@ pub use graph::*;
pub use node::*; pub use node::*;
pub use node_slot::*; pub use node_slot::*;
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[derive(Error, Display, Debug, Eq, PartialEq)] #[derive(Error, Debug, Eq, PartialEq)]
pub enum RenderGraphError { pub enum RenderGraphError {
#[display("node {_0:?} does not exist")] #[error("node {0:?} does not exist")]
#[error(ignore)]
InvalidNode(InternedRenderLabel), InvalidNode(InternedRenderLabel),
#[display("output node slot does not exist")] #[error("output node slot does not exist")]
#[error(ignore)]
InvalidOutputNodeSlot(SlotLabel), InvalidOutputNodeSlot(SlotLabel),
#[display("input node slot does not exist")] #[error("input node slot does not exist")]
#[error(ignore)]
InvalidInputNodeSlot(SlotLabel), InvalidInputNodeSlot(SlotLabel),
#[display("node does not match the given type")] #[error("node does not match the given type")]
WrongNodeType, WrongNodeType,
#[display("attempted to connect output slot {output_slot} from node {output_node:?} to incompatible input slot {input_slot} from node {input_node:?}")] #[error("attempted to connect output slot {output_slot} from node {output_node:?} to incompatible input slot {input_slot} from node {input_node:?}")]
MismatchedNodeSlots { MismatchedNodeSlots {
output_node: InternedRenderLabel, output_node: InternedRenderLabel,
output_slot: usize, output_slot: usize,
input_node: InternedRenderLabel, input_node: InternedRenderLabel,
input_slot: usize, input_slot: usize,
}, },
#[display("attempted to add an edge that already exists")] #[error("attempted to add an edge that already exists")]
#[error(ignore)]
EdgeAlreadyExists(Edge), EdgeAlreadyExists(Edge),
#[display("attempted to remove an edge that does not exist")] #[error("attempted to remove an edge that does not exist")]
#[error(ignore)]
EdgeDoesNotExist(Edge), EdgeDoesNotExist(Edge),
#[display("node {node:?} has an unconnected input slot {input_slot}")] #[error("node {node:?} has an unconnected input slot {input_slot}")]
UnconnectedNodeInputSlot { UnconnectedNodeInputSlot {
node: InternedRenderLabel, node: InternedRenderLabel,
input_slot: usize, input_slot: usize,
}, },
#[display("node {node:?} has an unconnected output slot {output_slot}")] #[error("node {node:?} has an unconnected output slot {output_slot}")]
UnconnectedNodeOutputSlot { UnconnectedNodeOutputSlot {
node: InternedRenderLabel, node: InternedRenderLabel,
output_slot: usize, output_slot: usize,
}, },
#[display("node {node:?} input slot {input_slot} already occupied by {occupied_by_node:?}")] #[error("node {node:?} input slot {input_slot} already occupied by {occupied_by_node:?}")]
NodeInputSlotAlreadyOccupied { NodeInputSlotAlreadyOccupied {
node: InternedRenderLabel, node: InternedRenderLabel,
input_slot: usize, input_slot: usize,

View file

@ -14,8 +14,8 @@ use bevy_ecs::{
world::{FromWorld, World}, world::{FromWorld, World},
}; };
use core::fmt::Debug; use core::fmt::Debug;
use derive_more::derive::{Display, Error, From};
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
use thiserror::Error;
use variadics_please::all_tuples_with_size; use variadics_please::all_tuples_with_size;
pub use bevy_render_macros::RenderLabel; pub use bevy_render_macros::RenderLabel;
@ -98,16 +98,16 @@ pub trait Node: Downcast + Send + Sync + 'static {
impl_downcast!(Node); impl_downcast!(Node);
#[derive(Error, Display, Debug, Eq, PartialEq, From)] #[derive(Error, Debug, Eq, PartialEq)]
pub enum NodeRunError { pub enum NodeRunError {
#[display("encountered an input slot error")] #[error("encountered an input slot error")]
InputSlotError(InputSlotError), InputSlotError(#[from] InputSlotError),
#[display("encountered an output slot error")] #[error("encountered an output slot error")]
OutputSlotError(OutputSlotError), OutputSlotError(#[from] OutputSlotError),
#[display("encountered an error when running a sub-graph")] #[error("encountered an error when running a sub-graph")]
RunSubGraphError(RunSubGraphError), RunSubGraphError(#[from] RunSubGraphError),
#[display("encountered an error when executing draw command")] #[error("encountered an error when executing draw command")]
DrawError(DrawError), DrawError(#[from] DrawError),
} }
/// A collection of input and output [`Edges`](Edge) for a [`Node`]. /// A collection of input and output [`Edges`](Edge) for a [`Node`].

View file

@ -8,8 +8,8 @@ use bevy_ecs::{
}; };
use bevy_utils::TypeIdMap; use bevy_utils::TypeIdMap;
use core::{any::TypeId, fmt::Debug, hash::Hash}; use core::{any::TypeId, fmt::Debug, hash::Hash};
use derive_more::derive::{Display, Error};
use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
use thiserror::Error;
use variadics_please::all_tuples; use variadics_please::all_tuples;
/// A draw function used to draw [`PhaseItem`]s. /// A draw function used to draw [`PhaseItem`]s.
@ -35,14 +35,13 @@ pub trait Draw<P: PhaseItem>: Send + Sync + 'static {
) -> Result<(), DrawError>; ) -> Result<(), DrawError>;
} }
#[derive(Error, Display, Debug, PartialEq, Eq)] #[derive(Error, Debug, PartialEq, Eq)]
pub enum DrawError { pub enum DrawError {
#[display("Failed to execute render command {_0:?}")] #[error("Failed to execute render command {0:?}")]
#[error(ignore)]
RenderCommandFailure(&'static str), RenderCommandFailure(&'static str),
#[display("Failed to get execute view query")] #[error("Failed to get execute view query")]
InvalidViewQuery, InvalidViewQuery,
#[display("View entity not found")] #[error("View entity not found")]
ViewEntityNotFound, ViewEntityNotFound,
} }

View file

@ -11,8 +11,8 @@ use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::{SystemParam, SystemParamItem}; use bevy_ecs::system::{SystemParam, SystemParamItem};
pub use bevy_render_macros::AsBindGroup; pub use bevy_render_macros::AsBindGroup;
use core::ops::Deref; use core::ops::Deref;
use derive_more::derive::{Display, Error};
use encase::ShaderType; use encase::ShaderType;
use thiserror::Error;
use wgpu::{BindGroupEntry, BindGroupLayoutEntry, BindingResource, TextureViewDimension}; use wgpu::{BindGroupEntry, BindGroupLayoutEntry, BindingResource, TextureViewDimension};
define_atomic_id!(BindGroupId); define_atomic_id!(BindGroupId);
@ -401,14 +401,14 @@ pub trait AsBindGroup {
} }
/// An error that occurs during [`AsBindGroup::as_bind_group`] calls. /// An error that occurs during [`AsBindGroup::as_bind_group`] calls.
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum AsBindGroupError { pub enum AsBindGroupError {
/// The bind group could not be generated. Try again next frame. /// The bind group could not be generated. Try again next frame.
#[display("The bind group could not be generated")] #[error("The bind group could not be generated")]
RetryNextUpdate, RetryNextUpdate,
#[display("Create the bind group via `as_bind_group()` instead")] #[error("Create the bind group via `as_bind_group()` instead")]
CreateBindGroupDirectly, CreateBindGroupDirectly,
#[display("At binding index {_0}, the provided image sampler `{_1}` does not match the required sampler type(s) `{_2}`.")] #[error("At binding index {0}, the provided image sampler `{1}` does not match the required sampler type(s) `{2}`.")]
InvalidSamplerType(u32, String, String), InvalidSamplerType(u32, String, String),
} }

View file

@ -18,9 +18,9 @@ use bevy_utils::{
HashMap, HashSet, HashMap, HashSet,
}; };
use core::{future::Future, hash::Hash, mem, ops::Deref}; use core::{future::Future, hash::Hash, mem, ops::Deref};
use derive_more::derive::{Display, Error, From};
use naga::valid::Capabilities; use naga::valid::Capabilities;
use std::sync::{Mutex, PoisonError}; use std::sync::{Mutex, PoisonError};
use thiserror::Error;
#[cfg(feature = "shader_format_spirv")] #[cfg(feature = "shader_format_spirv")]
use wgpu::util::make_spirv; use wgpu::util::make_spirv;
use wgpu::{ use wgpu::{
@ -974,19 +974,17 @@ fn create_pipeline_task(
} }
/// Type of error returned by a [`PipelineCache`] when the creation of a GPU pipeline object failed. /// Type of error returned by a [`PipelineCache`] when the creation of a GPU pipeline object failed.
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum PipelineCacheError { pub enum PipelineCacheError {
#[display( #[error(
"Pipeline could not be compiled because the following shader could not be loaded: {_0:?}" "Pipeline could not be compiled because the following shader could not be loaded: {0:?}"
)] )]
#[error(ignore)]
ShaderNotLoaded(AssetId<Shader>), ShaderNotLoaded(AssetId<Shader>),
#[error(transparent)]
ProcessShaderError(naga_oil::compose::ComposerError), ProcessShaderError(#[from] naga_oil::compose::ComposerError),
#[display("Shader import not yet available.")] #[error("Shader import not yet available.")]
ShaderImportNotYetAvailable, ShaderImportNotYetAvailable,
#[display("Could not create shader module: {_0}")] #[error("Could not create shader module: {0}")]
#[error(ignore)]
CreateShaderModule(String), CreateShaderModule(String),
} }

View file

@ -13,7 +13,7 @@ use bevy_utils::{
Entry, HashMap, Entry, HashMap,
}; };
use core::{fmt::Debug, hash::Hash}; use core::{fmt::Debug, hash::Hash};
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
pub trait SpecializedRenderPipeline { pub trait SpecializedRenderPipeline {
type Key: Clone + Hash + PartialEq + Eq; type Key: Clone + Hash + PartialEq + Eq;
@ -183,7 +183,8 @@ impl<S: SpecializedMeshPipeline> SpecializedMeshPipelines<S> {
} }
} }
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum SpecializedMeshPipelineError { pub enum SpecializedMeshPipelineError {
MissingVertexAttribute(MissingVertexAttributeError), #[error(transparent)]
MissingVertexAttribute(#[from] MissingVertexAttributeError),
} }

View file

@ -4,20 +4,22 @@ use alloc::borrow::Cow;
use bevy_asset::{io::Reader, Asset, AssetLoader, AssetPath, Handle, LoadContext}; use bevy_asset::{io::Reader, Asset, AssetLoader, AssetPath, Handle, LoadContext};
use bevy_reflect::TypePath; use bevy_reflect::TypePath;
use core::marker::Copy; use core::marker::Copy;
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
define_atomic_id!(ShaderId); define_atomic_id!(ShaderId);
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum ShaderReflectError { pub enum ShaderReflectError {
WgslParse(naga::front::wgsl::ParseError), #[error(transparent)]
WgslParse(#[from] naga::front::wgsl::ParseError),
#[cfg(feature = "shader_format_glsl")] #[cfg(feature = "shader_format_glsl")]
#[display("GLSL Parse Error: {_0:?}")] #[error("GLSL Parse Error: {0:?}")]
#[error(ignore)]
GlslParse(Vec<naga::front::glsl::Error>), GlslParse(Vec<naga::front::glsl::Error>),
#[cfg(feature = "shader_format_spirv")] #[cfg(feature = "shader_format_spirv")]
SpirVParse(naga::front::spv::Error), #[error(transparent)]
Validation(naga::WithSpan<naga::valid::ValidationError>), SpirVParse(#[from] naga::front::spv::Error),
#[error(transparent)]
Validation(#[from] naga::WithSpan<naga::valid::ValidationError>),
} }
/// A shader, as defined by its [`ShaderSource`](wgpu::ShaderSource) and [`ShaderStage`](naga::ShaderStage) /// A shader, as defined by its [`ShaderSource`](wgpu::ShaderSource) and [`ShaderStage`](naga::ShaderStage)
/// This is an "unprocessed" shader. It can contain preprocessor directives. /// This is an "unprocessed" shader. It can contain preprocessor directives.
@ -244,12 +246,12 @@ impl From<&Source> for naga_oil::compose::ShaderType {
pub struct ShaderLoader; pub struct ShaderLoader;
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum ShaderLoaderError { pub enum ShaderLoaderError {
#[display("Could not load shader: {_0}")] #[error("Could not load shader: {0}")]
Io(std::io::Error), Io(#[from] std::io::Error),
#[display("Could not parse shader: {_0}")] #[error("Could not parse shader: {0}")]
Parse(alloc::string::FromUtf8Error), Parse(#[from] alloc::string::FromUtf8Error),
} }
impl AssetLoader for ShaderLoader { impl AssetLoader for ShaderLoader {

View file

@ -4,8 +4,8 @@ use bevy_utils::tracing::info_span;
use bevy_utils::HashMap; use bevy_utils::HashMap;
use alloc::{borrow::Cow, collections::VecDeque}; use alloc::{borrow::Cow, collections::VecDeque};
use derive_more::derive::{Display, Error, From};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use thiserror::Error;
use crate::{ use crate::{
diagnostic::internal::{DiagnosticsRecorder, RenderDiagnosticsMutex}, diagnostic::internal::{DiagnosticsRecorder, RenderDiagnosticsMutex},
@ -29,29 +29,30 @@ use crate::{
/// [`CommandBuffer`]: wgpu::CommandBuffer /// [`CommandBuffer`]: wgpu::CommandBuffer
pub(crate) struct RenderGraphRunner; pub(crate) struct RenderGraphRunner;
#[derive(Error, Display, Debug, From)] #[derive(Error, Debug)]
pub enum RenderGraphRunnerError { pub enum RenderGraphRunnerError {
NodeRunError(NodeRunError), #[error(transparent)]
#[display("node output slot not set (index {slot_index}, name {slot_name})")] NodeRunError(#[from] NodeRunError),
#[error("node output slot not set (index {slot_index}, name {slot_name})")]
EmptyNodeOutputSlot { EmptyNodeOutputSlot {
type_name: &'static str, type_name: &'static str,
slot_index: usize, slot_index: usize,
slot_name: Cow<'static, str>, slot_name: Cow<'static, str>,
}, },
#[display("graph '{sub_graph:?}' could not be run because slot '{slot_name}' at index {slot_index} has no value")] #[error("graph '{sub_graph:?}' could not be run because slot '{slot_name}' at index {slot_index} has no value")]
MissingInput { MissingInput {
slot_index: usize, slot_index: usize,
slot_name: Cow<'static, str>, slot_name: Cow<'static, str>,
sub_graph: Option<InternedRenderSubGraph>, sub_graph: Option<InternedRenderSubGraph>,
}, },
#[display("attempted to use the wrong type for input slot")] #[error("attempted to use the wrong type for input slot")]
MismatchedInputSlotType { MismatchedInputSlotType {
slot_index: usize, slot_index: usize,
label: SlotLabel, label: SlotLabel,
expected: SlotType, expected: SlotType,
actual: SlotType, actual: SlotType,
}, },
#[display( #[error(
"node (name: '{node_name:?}') has {slot_count} input slots, but was provided {value_count} values" "node (name: '{node_name:?}') has {slot_count} input slots, but was provided {value_count} values"
)] )]
MismatchedInputCount { MismatchedInputCount {

View file

@ -29,11 +29,8 @@ bevy_render = { path = "../bevy_render", version = "0.15.0-dev", optional = true
# other # other
serde = { version = "1.0", features = ["derive"], optional = true } serde = { version = "1.0", features = ["derive"], optional = true }
uuid = { version = "1.1", features = ["v4"] } uuid = { version = "1.1", features = ["v4"] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
[dev-dependencies] [dev-dependencies]
postcard = { version = "1.0", features = ["alloc"] } postcard = { version = "1.0", features = ["alloc"] }

View file

@ -7,9 +7,9 @@ use bevy_ecs::{
world::{FromWorld, World}, world::{FromWorld, World},
}; };
use bevy_reflect::TypeRegistryArc; use bevy_reflect::TypeRegistryArc;
use derive_more::derive::{Display, Error, From};
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::de::DeserializeSeed; use serde::de::DeserializeSeed;
use thiserror::Error;
/// Asset loader for a Bevy dynamic scene (`.scn` / `.scn.ron`). /// Asset loader for a Bevy dynamic scene (`.scn` / `.scn.ron`).
/// ///
@ -30,14 +30,14 @@ impl FromWorld for SceneLoader {
/// Possible errors that can be produced by [`SceneLoader`] /// Possible errors that can be produced by [`SceneLoader`]
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum SceneLoaderError { pub enum SceneLoaderError {
/// An [IO Error](std::io::Error) /// An [IO Error](std::io::Error)
#[display("Error while trying to read the scene file: {_0}")] #[error("Error while trying to read the scene file: {0}")]
Io(std::io::Error), Io(#[from] std::io::Error),
/// A [RON Error](ron::error::SpannedError) /// A [RON Error](ron::error::SpannedError)
#[display("Could not parse RON: {_0}")] #[error("Could not parse RON: {0}")]
RonSpannedError(ron::error::SpannedError), RonSpannedError(#[from] ron::error::SpannedError),
} }
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]

View file

@ -10,7 +10,7 @@ use bevy_ecs::{
use bevy_hierarchy::{AddChild, BuildChildren, DespawnRecursiveExt, Parent}; use bevy_hierarchy::{AddChild, BuildChildren, DespawnRecursiveExt, Parent};
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
use bevy_utils::{HashMap, HashSet}; use bevy_utils::{HashMap, HashSet};
use derive_more::derive::{Display, Error}; use thiserror::Error;
use uuid::Uuid; use uuid::Uuid;
/// Triggered on a scene's parent entity when [`crate::SceneInstance`] becomes ready to use. /// Triggered on a scene's parent entity when [`crate::SceneInstance`] becomes ready to use.
@ -75,22 +75,22 @@ pub struct SceneSpawner {
} }
/// Errors that can occur when spawning a scene. /// Errors that can occur when spawning a scene.
#[derive(Error, Display, Debug)] #[derive(Error, Debug)]
pub enum SceneSpawnError { pub enum SceneSpawnError {
/// Scene contains an unregistered component type. /// Scene contains an unregistered component type.
#[display("scene contains the unregistered component `{type_path}`. consider adding `#[reflect(Component)]` to your type")] #[error("scene contains the unregistered component `{type_path}`. consider adding `#[reflect(Component)]` to your type")]
UnregisteredComponent { UnregisteredComponent {
/// Type of the unregistered component. /// Type of the unregistered component.
type_path: String, type_path: String,
}, },
/// Scene contains an unregistered resource type. /// Scene contains an unregistered resource type.
#[display("scene contains the unregistered resource `{type_path}`. consider adding `#[reflect(Resource)]` to your type")] #[error("scene contains the unregistered resource `{type_path}`. consider adding `#[reflect(Resource)]` to your type")]
UnregisteredResource { UnregisteredResource {
/// Type of the unregistered resource. /// Type of the unregistered resource.
type_path: String, type_path: String,
}, },
/// Scene contains an unregistered type. /// Scene contains an unregistered type.
#[display( #[error(
"scene contains the unregistered type `{std_type_name}`. \ "scene contains the unregistered type `{std_type_name}`. \
consider reflecting it with `#[derive(Reflect)]` \ consider reflecting it with `#[derive(Reflect)]` \
and registering the type using `app.register_type::<T>()`" and registering the type using `app.register_type::<T>()`"
@ -100,7 +100,7 @@ pub enum SceneSpawnError {
std_type_name: String, std_type_name: String,
}, },
/// Scene contains an unregistered type which has a `TypePath`. /// Scene contains an unregistered type which has a `TypePath`.
#[display( #[error(
"scene contains the reflected type `{type_path}` but it was not found in the type registry. \ "scene contains the reflected type `{type_path}` but it was not found in the type registry. \
consider registering the type using `app.register_type::<T>()``" consider registering the type using `app.register_type::<T>()``"
)] )]
@ -109,19 +109,19 @@ pub enum SceneSpawnError {
type_path: String, type_path: String,
}, },
/// Scene contains a proxy without a represented type. /// Scene contains a proxy without a represented type.
#[display("scene contains dynamic type `{type_path}` without a represented type. consider changing this using `set_represented_type`.")] #[error("scene contains dynamic type `{type_path}` without a represented type. consider changing this using `set_represented_type`.")]
NoRepresentedType { NoRepresentedType {
/// The dynamic instance type. /// The dynamic instance type.
type_path: String, type_path: String,
}, },
/// Dynamic scene with the given id does not exist. /// Dynamic scene with the given id does not exist.
#[display("scene does not exist")] #[error("scene does not exist")]
NonExistentScene { NonExistentScene {
/// Id of the non-existent dynamic scene. /// Id of the non-existent dynamic scene.
id: AssetId<DynamicScene>, id: AssetId<DynamicScene>,
}, },
/// Scene with the given id does not exist. /// Scene with the given id does not exist.
#[display("scene does not exist")] #[error("scene does not exist")]
NonExistentRealScene { NonExistentRealScene {
/// Id of the non-existent scene. /// Id of the non-existent scene.
id: AssetId<Scene>, id: AssetId<Scene>,

View file

@ -37,11 +37,8 @@ bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bytemuck = { version = "1", features = ["derive", "must_cast"] } bytemuck = { version = "1", features = ["derive", "must_cast"] }
fixedbitset = "0.5" fixedbitset = "0.5"
guillotiere = "0.6.0" guillotiere = "0.6.0"
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
rectangle-pack = "0.4" rectangle-pack = "0.4"
bitflags = "2.3" bitflags = "2.3"
radsort = "0.1" radsort = "0.1"

View file

@ -9,19 +9,19 @@ use bevy_utils::{
tracing::{debug, error, warn}, tracing::{debug, error, warn},
HashMap, HashMap,
}; };
use derive_more::derive::{Display, Error};
use rectangle_pack::{ use rectangle_pack::{
contains_smallest_box, pack_rects, volume_heuristic, GroupedRectsToPlace, PackedLocation, contains_smallest_box, pack_rects, volume_heuristic, GroupedRectsToPlace, PackedLocation,
RectToInsert, TargetBin, RectToInsert, TargetBin,
}; };
use thiserror::Error;
use crate::{TextureAtlasLayout, TextureAtlasSources}; use crate::{TextureAtlasLayout, TextureAtlasSources};
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum TextureAtlasBuilderError { pub enum TextureAtlasBuilderError {
#[display("could not pack textures into an atlas within the given bounds")] #[error("could not pack textures into an atlas within the given bounds")]
NotEnoughSpace, NotEnoughSpace,
#[display("added a texture with the wrong format in an atlas")] #[error("added a texture with the wrong format in an atlas")]
WrongFormat, WrongFormat,
} }

View file

@ -32,11 +32,7 @@ bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
# other # other
cosmic-text = { version = "0.12", features = ["shape-run-cache"] } cosmic-text = { version = "0.12", features = ["shape-run-cache"] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error",
"from",
"display",
] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
smallvec = "1.13" smallvec = "1.13"
unicode-bidi = "0.3.13" unicode-bidi = "0.3.13"

View file

@ -1,19 +1,17 @@
use cosmic_text::CacheKey; use cosmic_text::CacheKey;
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[derive(Debug, PartialEq, Eq, Error, Display)] #[derive(Debug, PartialEq, Eq, Error)]
/// Errors related to the textsystem /// Errors related to the textsystem
pub enum TextError { pub enum TextError {
/// Font was not found, this could be that the font has not yet been loaded, or /// Font was not found, this could be that the font has not yet been loaded, or
/// that the font failed to load for some other reason /// that the font failed to load for some other reason
#[display("font not found")] #[error("font not found")]
NoSuchFont, NoSuchFont,
/// Failed to add glyph to a newly created atlas for some reason /// Failed to add glyph to a newly created atlas for some reason
#[display("failed to add glyph to newly-created atlas {_0:?}")] #[error("failed to add glyph to newly-created atlas {0:?}")]
#[error(ignore)]
FailedToAddGlyph(u16), FailedToAddGlyph(u16),
/// Failed to get scaled glyph image for cache key /// Failed to get scaled glyph image for cache key
#[display("failed to get scaled glyph image for cache key: {_0:?}")] #[error("failed to get scaled glyph image for cache key: {0:?}")]
#[error(ignore)]
FailedToGetGlyphImage(CacheKey), FailedToGetGlyphImage(CacheKey),
} }

View file

@ -1,6 +1,6 @@
use crate::Font; use crate::Font;
use bevy_asset::{io::Reader, AssetLoader, LoadContext}; use bevy_asset::{io::Reader, AssetLoader, LoadContext};
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
#[derive(Default)] #[derive(Default)]
/// An [`AssetLoader`] for [`Font`]s, for use by the [`AssetServer`](bevy_asset::AssetServer) /// An [`AssetLoader`] for [`Font`]s, for use by the [`AssetServer`](bevy_asset::AssetServer)
@ -8,12 +8,14 @@ pub struct FontLoader;
/// Possible errors that can be produced by [`FontLoader`] /// Possible errors that can be produced by [`FontLoader`]
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum FontLoaderError { pub enum FontLoaderError {
/// The contents that could not be parsed /// The contents that could not be parsed
Content(cosmic_text::ttf_parser::FaceParsingError), #[error(transparent)]
Content(#[from] cosmic_text::ttf_parser::FaceParsingError),
/// An [IO](std::io) Error /// An [IO](std::io) Error
Io(std::io::Error), #[error(transparent)]
Io(#[from] std::io::Error),
} }
impl AssetLoader for FontLoader { impl AssetLoader for FontLoader {

View file

@ -20,11 +20,8 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy", "bevy",
], optional = true } ], optional = true }
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
[dev-dependencies] [dev-dependencies]
bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" } bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }

View file

@ -6,7 +6,7 @@ use bevy_ecs::{
system::{Query, SystemParam}, system::{Query, SystemParam},
}; };
use bevy_hierarchy::{HierarchyQueryExt, Parent}; use bevy_hierarchy::{HierarchyQueryExt, Parent};
use derive_more::derive::{Display, Error}; use thiserror::Error;
use crate::components::{GlobalTransform, Transform}; use crate::components::{GlobalTransform, Transform};
@ -64,20 +64,17 @@ fn map_error(err: QueryEntityError, ancestor: bool) -> ComputeGlobalTransformErr
} }
/// Error returned by [`TransformHelper::compute_global_transform`]. /// Error returned by [`TransformHelper::compute_global_transform`].
#[derive(Debug, Error, Display)] #[derive(Debug, Error)]
pub enum ComputeGlobalTransformError { pub enum ComputeGlobalTransformError {
/// The entity or one of its ancestors is missing the [`Transform`] component. /// The entity or one of its ancestors is missing the [`Transform`] component.
#[display("The entity {_0:?} or one of its ancestors is missing the `Transform` component")] #[error("The entity {0:?} or one of its ancestors is missing the `Transform` component")]
#[error(ignore)]
MissingTransform(Entity), MissingTransform(Entity),
/// The entity does not exist. /// The entity does not exist.
#[display("The entity {_0:?} does not exist")] #[error("The entity {0:?} does not exist")]
#[error(ignore)]
NoSuchEntity(Entity), NoSuchEntity(Entity),
/// An ancestor is missing. /// An ancestor is missing.
/// This probably means that your hierarchy has been improperly maintained. /// This probably means that your hierarchy has been improperly maintained.
#[display("The ancestor {_0:?} is missing")] #[error("The ancestor {0:?} is missing")]
#[error(ignore)]
MalformedHierarchy(Entity), MalformedHierarchy(Entity),
} }

View file

@ -36,11 +36,8 @@ bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
taffy = { version = "0.6" } taffy = { version = "0.6" }
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
bytemuck = { version = "1.5", features = ["derive"] } bytemuck = { version = "1.5", features = ["derive"] }
derive_more = { version = "1", default-features = false, features = [ thiserror = { version = "2", default-features = false }
"error", derive_more = { version = "1", default-features = false, features = ["from"] }
"from",
"display",
] }
nonmax = "0.5" nonmax = "0.5"
smallvec = "1.11" smallvec = "1.11"
accesskit = "0.17" accesskit = "0.17"

View file

@ -1,7 +1,7 @@
use bevy_math::Vec2; use bevy_math::Vec2;
use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use core::ops::{Div, DivAssign, Mul, MulAssign, Neg}; use core::ops::{Div, DivAssign, Mul, MulAssign, Neg};
use derive_more::derive::{Display, Error}; use thiserror::Error;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
@ -174,11 +174,11 @@ impl Neg for Val {
} }
} }
#[derive(Debug, Eq, PartialEq, Clone, Copy, Error, Display)] #[derive(Debug, Eq, PartialEq, Clone, Copy, Error)]
pub enum ValArithmeticError { pub enum ValArithmeticError {
#[display("the variants of the Vals don't match")] #[error("the variants of the Vals don't match")]
NonIdenticalVariants, NonIdenticalVariants,
#[display("the given variant of Val is not evaluateable (non-numeric)")] #[error("the given variant of Val is not evaluateable (non-numeric)")]
NonEvaluateable, NonEvaluateable,
} }

View file

@ -19,7 +19,7 @@ use bevy_sprite::BorderRect;
use bevy_transform::components::Transform; use bevy_transform::components::Transform;
use bevy_utils::tracing::warn; use bevy_utils::tracing::warn;
use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged}; use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
use derive_more::derive::{Display, Error, From}; use thiserror::Error;
use ui_surface::UiSurface; use ui_surface::UiSurface;
use bevy_text::ComputedTextBlock; use bevy_text::ComputedTextBlock;
@ -63,11 +63,11 @@ impl Default for LayoutContext {
} }
} }
#[derive(Debug, Error, Display, From)] #[derive(Debug, Error)]
pub enum LayoutError { pub enum LayoutError {
#[display("Invalid hierarchy")] #[error("Invalid hierarchy")]
InvalidHierarchy, InvalidHierarchy,
#[display("Taffy error: {_0}")] #[error("Taffy error: {0}")]
TaffyError(taffy::TaffyError), TaffyError(taffy::TaffyError),
} }

Some files were not shown because too many files have changed in this diff Show more