Matching a vector and transfer ownership of all elements without using slice

I want to do something like this:

enum Foo {
  Empty,
  Single(String),
  Multiple(Vec<String>),
}

fn convert(xs: Vec<String>) -> Foo {
  match xs {
    [] => Foo::Empty,
    [x] => Foo::Single(x),
    xs => Foo::Multiple(xs),
  }
}

The problems:

  1. A Vec is not an array, so the above code wouldn't compile.
  2. Using slice would require cloning.

That's not possible. From Rust's perspective Vec is just a 3-element struct, and Rust doesn't even know it has content.

Write if/else instead.

1 Like

The closest I can come up with is this:

fn convert(mut xs: Vec<String>) -> Foo {
  match xs.len() {
    0 => Foo::Empty,
    1 => Foo::Single(xs.pop().unwrap()),
    _ => Foo::Multiple(xs),
  }
}
1 Like
fn convert(mut xs: Vec<String>) -> Foo {
    match &mut *xs {
        [] => Foo::Empty,
        [x] => Foo::Single(std::mem::take(x)),
        _ => Foo::Multiple(xs),
    }
}
2 Likes