Matching templates within a framework
I want to use pattern matching to validate the inside of a struct without creating a new struct. I'm trying to change the meaning of a structure as an exercise (I know mem::swap
exists).
Swapping means matching the structure value and then replacing the matching values. As well as let him x = {10,20,30}; x.swap(10,30)
give {30,20,10}
.
I want to be able, but I can't
#[derive(Debug, Clone, Copy)]
struct Color {
r: u8,
g: u8,
b: u8,
a: u8,
}
impl Color {
fn swap(mut self, first: u8, second: u8) -> Color {
match (first) {
self.r => {
match (second) {
self.b => {
self.r = second;
self.b = first;
},
self.g => {
self.r = second;
self.g = first;
},
self.a => {
self.r = second;
self.a = first;
},
_ => {},
}
},
_ => {}
}
Color {
r: self.r,
g: self.g,
b: self.b,
a: self.a,
}
}
}
fn main() {
let c = Color {
r: 255,
g: 200,
b: 10,
a: 30,
};
let color = c.swap(c.r, c.a);
println!("{:?}", color);
}
The code is not valid, this is what I would like to accomplish. Is there a way to do this? I suppose I disagree with this approach.
source to share
Technically, there is a way to do this through pattern matching, but you probably never see it in practice. The downside is the use of match guard :
match first {
v if v == self.r => {
match second {
v if v == self.b => {
self.r = second;
self.b = first;
},
v if v == self.g => {
self.r = second;
self.g = first;
},
v if v == self.a => {
self.r = second;
self.a = first;
},
_ => {},
}
},
_ => {}
}
But that doesn't really use any useful part of pattern matching; it's just a bunch of if else articles:
if first == self.r {
if second == self.b {
self.r = second;
self.b = first;
} else if second == self.g {
self.r = second;
self.g = first;
} else if second == self.a {
self.r = second;
self.a = first;
}
}
You can choose shoehorn in some templates though:
let x1 = (first == self.r, first == self.g, first == self.b, first == self.a);
let x2 = (second == self.r, second == self.g, second == self.b, second == self.a);
match (x1, x2) {
((true, _, _, _), (_, true, _, _)) => {
self.r = second;
self.b = first;
}
((true, _, _, _), (_, _, true, _)) => {
self.r = second;
self.g = first;
}
((true, _, _, _), (_, _, _, true)) => {
self.r = second;
self.a = first;
}
_ => {}
}
source to share