let s = "1 2 3";
let parsed = s.parse::<S>();
assert_matches!(parsed, Ok(S([T(1), T(2), T(3)])));
Aside from whether it makes sense; it's intuitive for me to write it like this.
Unfortunately this doesn't work
error[E0529]: expected an array or slice, found `Vec<T>`
--> src/main.rs:20:34
|
20 | assert_matches!(parsed, Ok(S([T(1), T(2), T(3)])));
| ^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Vec<T>`
|
help: consider using `as_deref` here
|
20 | assert_matches!(parsed.as_deref(), Ok(S([T(1), T(2), T(3)])));
| +++++++++++
For more information about this error, try `rustc --explain E0529`.
When I used the compiler hint above, it didn't resolve the issue.
I can however do this:
assert_matches!(parsed, Ok(S(..)));
let s_inner = parsed.unwrap().0;
assert_matches!(s_inner.as_slice(), [T(1), T(2), T(3)]);
So my questions here are:
How should I've written the code to be idiomatic in the scenario above?
Yup. In particular, it is a consequence of this observation. You can't destructure a Vec using pattern matching - you have to either use regular tools like boolean comparisons, or pattern match on it as a slice.
Personally, I'd do the former. matches! supports match predicates, so you can even combine them:
let parsed = parsed.expect("some explanation for why parsing always returns Ok");
assert_matches!(parsed, S(elements) if elements == vec![T(1), T(2), T(3)]);
We may get deref patterns eventually, but it wouldn't apply to this (doubly) nested scenario.
Do you think it would be worthwhile for me to open an issue at rust-lang/rust to discuss clarifying the compiler error and hint for matching against Vec?
Something like:
"You can't use array/slice pattern matching for Vec<T> because it behaves like a struct.
hint: First convert Vec<T> to a slice &[T]"