bevyengine / bevyengine/bevy

Add `Option<Res>::cloned`

Open
#8,749 3 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Usability
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## What problem does this solve or what need does it fill?

`Res` does not implement `Clone`, but instead has a custom `clone` method. This does not play well when using an `Option` that you need to clone since `Option::cloned` requires the inner type to implement `Clone`.

## What solution would you like?

It would be nice to have an extension to `Option` that creates a custom `cloned` method that calls the custom `Res::clone` method. Then I could do something like this:

```rust
let slot_transfer_data = mouse_data
.cloned()
.filter(|m| m.location == MouseLocation::Slot)
.and_then(|m| m.inventory_index);
let map_transfer_data = mouse_data
.cloned()
.filter(|m| m.location == MouseLocation::Map)
.and_then(|m| camera.viewport_to_world_2d(camera_transform, m.position));
```

## What alternative(s) have you considered?

Right now my code looks like this:

```rust
let (slot_transfer_data, map_transfer_data) = if let Some(mouse_data) = mouse_data {
let slot_transfer_data = if mouse_data.location == MouseLocation::Slot {
mouse_data
.inventory_index
.zip(dragged_item.data)
.filter(|(dest_index, (dragged_index, _))| dest_index != dragged_index)
} else {
None
};
let map_transfer_data = if mouse_data.location == MouseLocation::Map {
camera
.viewport_to_world_2d(camera_transform, mouse_data.position)
.zip(dragged_item.data)
} else {
None
};
(slot_transfer_data, map_transfer_data)
} else {
(None, None)
};
```

IMO it's pretty messy. It's possible there's a simpler workaround already existing. I am new to Rust, so this is the best I've got.

## Additional context

I think I know just enough Rust to be able to contribute this if y'all think it's worth it. Also this change doesn't appear to be breaking, so that's nice.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.