@
-bindingsHere’s a fun thing you can do:
struct Data<'a> {
: [u8; 4],
header: &'a [u8]
body}
fn destructure(input: &[u8]) -> Data<'_> {
match input {
0x04, 0x07, a, b, c, d, body @ ..] => Data {
[: [*a, *b, *c, *d], body,
header},
, b, _, _, _, _, ..] => panic!("invalid magic number"),
[a0x04, 0x07, ..] => panic!("insufficient packet length"),
[, _b, ..] => panic!("invalid magic number, and insufficient packet length"),
[_a..] => panic!("insufficient packet length"),
[}
}
The things of note here are that you can use
..
to stand in for a sequence of
elements inside a slice (a “subslice pattern”),
and that you can write
name @ <some pattern>
to bind
the thing which was matched by a pattern to a
name.
Subslice
patterns were stabilized in Rust 1.42 and,
together with @
-bindings
(colloquially known as “at-bindings”) make
match
expressions very useful for
parsing.
I was motivated to write this post by a writing group we formed in the RPLCS Discord. Other posts by our group are listed here: https://www.catmonad.xyz/writing_group/.