The problem
Let's say we have a vector of strings, how can we print them easily?
let animals: Vec<String> = vec![String::from("snake"), String::from("camel"), String::from("crab")];
Trying to use the simplest way won't work:
println!("{}", animals);
We get the following error:
error[E0277]: `Vec<String>` doesn't implement `std::fmt::Display`
  --> src/main.rs:24:20
   |
24 |     println!("{}", animals);
   |                    ^^^^^^^ `Vec<String>` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Vec<String>`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
further referring us to E0277
We can do what was suggested:
println!("{:?}", animals);
will yield
["snake", "camel", "crab"]
and
println!("{:#?}", animals);
will yield:
[
    "snake",
    "camel",
    "crab",
]
Those are actually not bad, but I wanted to show them in a different way.
Primarily as an experiment to see how to implement Display in general for a vector.
Implement Display for Vec
The implementation should look something like this:
impl fmt::Display for Vec<String> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", "Something comes here")
    }
}
However, this will give us a compiler error:
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> src/main.rs:23:1
   |
23 | impl fmt::Display for Vec<String> {
   | ^^^^^^^^^^^^^^^^^^^^^^-----------
   | |                     |
   | |                     `Vec` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead
Referencing us to E0117.
How can we implement the Display trait for a vector in Rust?
We cannot as we can only implement traits to our own data types.
What about creating an alias for this type? Would crating a type-alias work?
How to implement traits for type aliases in Rust?
type Words = Vec<String>;
impl fmt::Display for Words {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", "Something comes here")
    }
}
let animals: Words = vec![String::from("snake"), String::from("camel"), String::from("crab")];
println!("{:?}", animals);
We can define the type-alias and we can even use it in the declaration of variables, but we cannot implement the Display trait on a type-alias to a standard type. Type-aliases are just that. Aliases. They are not separate types.
Using a one-element tuple-based struct
A working solution is to create a one-element tuple-based struct. Because it is a totally new type we can implement the Display trait for that.
struct Words(Vec<String>);
impl fmt::Display for Words {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0.join(","))
    }
}
This is then how to use it:
let animals: Words = Words(vec![String::from("snake"), String::from("camel"), String::from("crab")]);
println!("{}", animals);
It will print:
snake,camel,crab
The drawback is that this means we need to reference to the 0th element in the tuple so we must write animals.0 in order to access the real vector:
println!("{}", animals.0[0]);
println!("{}", animals.0[1]);
to print:
snake
camel
I don't think I like this.
The full example
examples/display-vector-of-strings/src/main.rs
use std::fmt;
// Try to implement Display for the Vec<String>
// impl fmt::Display for Vec<String> {
//     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//         write!(f, "{}", "Something comes here")
//     }
// }
// Try to use a type-alias:
// type Words = Vec<String>;
// impl fmt::Display for Words {
//     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//         write!(f, "{}", "Something comes here")
//     }
// }
struct Words(Vec<String>);
impl fmt::Display for Words {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0.join(","))
    }
}
fn main() {
    // plain vector
    //let animals: Vec<String> = vec![String::from("snake"), String::from("camel"), String::from("crab")];
    //println!("{}", animals);
    //println!("{:?}", animals);
    //println!("{:#?}", animals);
    // type alias
    //let animals: Words = vec![String::from("snake"), String::from("camel"), String::from("crab")];
    //println!("{:?}", animals);
    // one-element struct
    let animals: Words = Words(vec![String::from("snake"), String::from("camel"), String::from("crab")]);
    println!("{}", animals);
    println!("{}", animals.0[0]);
    println!("{}", animals.0[1]);
}
Conclusion
We could not implement Display for a vector of strings in a nice way. If we frequently need to print out a whole vector of strings other than for debugging, then we might want to write a separate function or a macro for that.
