-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ecs): add Assume
and Unpack
traits for Result
conversion
#17739
base: main
Are you sure you want to change the base?
Conversation
Adds the following trait, and implements it for `Option`: ``` pub trait OptionExt<T> { fn unpack(self) -> Result<T, NoneError>; fn assume<E: Into<Box<dyn Error>>>(self, err: E) -> Result<T, Box<dyn Error>>; } ``` This allows for a more concise and readable way of handling `Option` values in Bevy systems that return `Result`s, by applying the question mark operator: ``` fn my_system(world: &World) -> bevy::ecs::Result { world.get::<MyComponent>(Entity::PLACEHOLDER).unpack()?; world.get_resource::<MyResource>().assume("My resource is missing")?; Ok(()) } ``` In future commits, more of Bevy's API will be converted to return `Result`s directly, but there will always be (non-)Bevy methods that return `Option` values, so this extension trait will have its place, regardless. Signed-off-by: Jean Mertz <[email protected]>
I think the better place for this trait at least is Rust std. Could you try opening the discussion there? |
I’m happy to, but I don’t suppose you propose waiting for that resolution? Any suggestion where it should live until/when it lands in Rust std? |
Yes I do? If it happens fast, it could be in rust 1.86 which may happen before (or around) the next version of Bevy |
I see. I would propose that both can be done in parallel; add the convenience methods in Bevy to help with fallible system adoption, and concurrently propose upstreaming the methods. If they are upstreamed, we can remove the custom impl here, if it's not upstreamed, then we don't need to change anything on our side. Regardless, I'll find some time next week to propose the methods upstream. |
I would prefer to wait, this is not that much better that it's worth changing then reverting |
I like the end result, but I'm not super keen on shipping this in Bevy itself. Extension traits on super common types like Option are likely to badly confuse beginners. Would enthusiastically support using this if it was in the |
I haven’t looked too deep yet, but |
Alright, I looked into it more, I really don't see any chance of this getting upstreamed. For optional.assume(SomeError)? to (worst case): optional.ok_or(SomeError).map_err(Into::into)? (I should note that While I could make a case for For Having said all that. I'm happy to close this and use the extension trait in my own projects. I added this because it was proposed in #14275 (comment), but if we think the gain in convenience is too small for the cost of people having to learn non-std-Rust methods, then I can see that reasoning as well. |
We'll leave this open and let @cart decide when he gets around to it :) This is just a matter of taste IMO. |
Signed-off-by: Jean Mertz <[email protected]>
Signed-off-by: Jean Mertz <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good move, with some minor changes.
crates/bevy_utils/src/option_ext.rs
Outdated
@@ -0,0 +1,90 @@ | |||
//! Extensions to the [`Option`] type used in Bevy. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think the odds of these being included in std
are slim. And assume
, once Bevy's error type isn't just a boxed core Error, couldn't possibly live in std
. And even if unpack
were to land in std, it would likely be closer to the "years" timeframe than the "months" timeframe.
Agreed with Cart's feedback, and I'm fine to follow his direction on this. I agree with his / your assumption that upstreaming will be hard. |
Signed-off-by: Jean Mertz <[email protected]>
This PR has been rebased on main and all feedback has been resolved. |
Co-authored-by: Alice Cecile <[email protected]>
/// The error type returned by [`Assume::assume`]. | ||
type Error; | ||
|
||
/// Convert `Self<T>` to a `Result<T, Self::Error>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These docs will not be very helpful on mouse-over tooltips.
A round of documentation hardening for you :) New users are going to see these traits / methods pretty prominently, so I want to make sure that they're approachable and have the context needed to defend the design. |
Signed-off-by: Jean Mertz <[email protected]>
OptionExt
trait for Result
conversionAssume
and Unpack
traits for Result
conversion
Adds the following traits, and implements them for
Option
:This allows for a more concise and readable way of handling
Option
values in Bevy systems that returnResult
s, by applying the question mark operator:In future commits, more of Bevy's API will be converted to return
Result
s directly, but there will always be (non-)Bevy methods that returnOption
values, so this extension trait will have its place, regardless.This was suggested by @cart here: #14275 (comment)