The folllowing code works as expected (demo) but this requires two nested match {}
which I want to replace with just one.
#![allow(unused)]
use std::collections::hash_map::HashMap;
#[derive(Debug, Clone)]
struct NormalTransaction(f64);
// only normal transaction can be disputed.. BY DESIGN
#[derive(Debug, Clone)]
struct DisputeTransaction(NormalTransaction);
#[derive(Debug, Clone)]
enum Transaction {
Normal(NormalTransaction),
Dispute(DisputeTransaction),
}
fn main() {
let mut m = HashMap::new();
m.insert(1, Transaction::Normal(NormalTransaction(100.0)));
println!("before: {:#?}", m);
match m.get_mut(&1) {
Some(t) => match t {
Transaction::Normal(normal) => {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
_ => {}, // NA
}
_ => {}, // NA
}
println!("after: {:#?}", m);
}
Replacing the two match{}
with just one, as follows:
match m.get_mut(&1) {
Some(t @ Transaction::Normal(normal)) => {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
_ => {}, // NA
}
but it does not work, saying (demo):
error: borrow of moved value
--> src/main.rs:24:14
|
24 | Some(t @ Transaction::Normal(normal)) => {
| -^^^^^^^^^^^^^^^^^^^^^^^------^
| | |
| | value borrowed here after move
| value moved into `t` here
| move occurs because `t` has type `&mut Transaction` which does not implement the `Copy` trait
error[E0382]: borrow of moved value
--> src/main.rs:24:38
|
24 | Some(t @ Transaction::Normal(normal)) => {
| ------------------------^^^^^^-
| | |
| | value borrowed here after move
| value moved here
|
= note: move occurs because value has type `&mut Transaction`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving the value
|
24 | Some(ref t @ Transaction::Normal(normal)) => {
| +++
Is it possible to do the mutable binding and destructuring in single match case?
I don't know of a way to do it using a single match, but it doesn't look that bad if you use if let
s instead of matches:
if let Some(t) = m.get_mut(&1) {
if let Transaction::Normal(normal) = t {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}
}
Once let-chains lands I believe you should also be able to write
if let Some(t) = m.get_mut(&1) && let Transaction::Normal(normal) = t {
*t = Transaction::Dispute(DisputeTransaction(normal.clone()));
}