How to create a function interface that computes its output from a vec input using a thread

What's missing from approach 4 is the conversion from Vec<String> to Vec<&str> within your worker.

This can be achieved with a function like this:

fn slice_as_ref(s: &[String]) -> Vec<&str> {
    s.iter().map(|s| s.as_str()).collect()
}

See it in action here: playground.