Reputation: 24547
A library presents me with a deeply nested data structure that I would like to match on. It contains Vec
s internally. I would like something like one of the commented out lines to work:
struct Foo {
bar: Vec<bool>,
}
let foo = Foo {
bar: vec![true, false],
};
match foo {
// Foo{bar:[true,false]} => Ok(()), // expected an array or slice, found Vec<bool>
// Foo{bar:&[true, false]} => Ok(()), // expected struct `Vec`, found reference
// Foo{bar:vec![true,false]} => Ok(()), // Arbitrary expressions aren't allowed in patterns
Foo { bar: v } => match v.as_slice() {
[true, false] => Ok(()),
_ => bail!("match failed!"),
}, // Ugly when nesting deeply
_ => bail!("match failed!"),
}
The match statement can be broken into smaller pieces that first do some dereferencing/unpacking on the value being matched, turning it into a slice first. I am currently doing this in my code, but it is quite ugly, and obscures the structure of the thing being destructured.
The issue is that Vec
is in the standard library, not part of the language, but I'm still hoping there is some pattern matching magic that can get around this.
Upvotes: 5
Views: 2620
Reputation: 42207
No, pattern-matching vecs (let alone in-place) is not currently supported. Currently, Rust only supports a somewhat limited forms of slice patterns, and even that is fairly recent (1.42).
You could use some of the other Rust facilities to make the code slightly terser but that's about it e.g. if let
or matches!
match foo {
Foo { bar: v } if matches!(v.as_slice(), [true, false]) => Ok(()),
_ => bail!("match failed!"),
}
Upvotes: 7