[][src]Macro improved_slice_patterns::match_vec

macro_rules! match_vec {
    (@make_pat; ($($acc:tt)*), $x:ident @ .., $($rest:tt)*) => { ... };
    (@make_pat; ($($acc:tt)*), $variant:ident ($x:ident).., $($rest:tt)*) => { ... };
    (@make_pat; ($($acc:tt)*), .., $($rest:tt)*) => { ... };
    (@make_pat; ($($acc:tt)*), $x:pat, $($rest:tt)*) => { ... };
    (@make_pat; (, $($acc:tt)*), $(,)*) => { ... };
    (@make_pat; ($($acc:tt)*), $(,)*) => { ... };
    (@make_filter; $x:ident @ .., $($rest:tt)*) => { ... };
    (@make_filter; $variant:ident ($x:ident).., $($rest:tt)*) => { ... };
    (@make_filter; .., $($rest:tt)*) => { ... };
    (@make_filter; $x:pat, $($rest:tt)*) => { ... };
    (@make_filter; $(,)*) => { ... };
    ($arg:expr; $( [$($args:tt)*] => $body:expr ),* $(,)*) => { ... };
}

Pattern-match on a vec using the syntax of slice_patterns.

Wraps the match body in Ok if there was a match; returns an Err containing the ownership of the vec otherwise.

Contrary to slice_patterns, this allows moving out of the Vec.

A variable length pattern (x @ ..) returns an iterator.

Example:

This code runs with edition 2018
#![feature(slice_patterns)]
use improved_slice_patterns::match_vec;

let vec = vec![Some(1), Some(2), Some(3), None];

let res = match_vec!(vec;
    [Some(_), y @ .., None] => {
        y.collect::<Vec<_>>()
    },
    [None, None] => {
        vec![]
    },
    [..] => vec![]
);

assert_eq!(res, Ok(vec![Some(2), Some(3)]));


let vec = vec![Some(1), Some(2), Some(3), None];

let res = match_vec!(vec;
    [Some(_), y @ .., Some(_)] => {
        y.collect::<Vec<_>>()
    },
    [None, None] => {
        vec![]
    },
);

assert!(res.is_err()); // there was no match