I want a Vec<CustomType>
to be joinable by &str
.
Here is a minimal example of what I've tried so far:
#[derive(Debug)]
struct Item {
string: String,
}
impl Item {
pub fn new(string: impl Into<String>) -> Self {
Self {
string: string.into(),
}
}
pub fn to_string(&self) -> &String {
&self.string
}
}
impl From<&Item> for &String {
fn from(item: &Item) -> Self {
&item.string
}
}
impl From<&Item> for &str {
fn from(item: &Item) -> Self {
&item.string.to_string()
}
}
fn main() {
let items = Vec::from([Item::new("Hello"), Item::new("world")]);
let string = items.join(" ");
println!("{}", string);
}
Which results in the error:
$ rustc jointrait.rs
error[E0599]: the method `join` exists for struct `Vec<Item>`, but its trait bounds were not satisfied
--> jointrait.rs:32:24
|
32 | let string = items.join(" ");
| ^^^^ method cannot be called on `Vec<Item>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`[Item]: Join<_>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.
The rustc help just says that some method is missing, but googling the error, I could not find out which method / trait I need to implement.
CodePudding user response:
In order for a list of T
s to be joinable, [T]
needs to implement Join<Separator>
.
If you look which things already implement Join
, you will find the following entry:
impl<S> Join<&str> for [S]
where
S: Borrow<str>
This means, everything that implements Borrow<str>
can be joined by a &str
separator. So all you have to do is implement Borrow<str>
for your struct:
use std::borrow::Borrow;
#[derive(Debug)]
struct Item {
string: String,
}
impl Item {
pub fn new(string: impl Into<String>) -> Self {
Self {
string: string.into(),
}
}
}
impl Borrow<str> for Item {
fn borrow(&self) -> &str {
&self.string
}
}
fn main() {
let items = Vec::from([Item::new("Hello"), Item::new("world")]);
let string = items.join(" ");
println!("{}", string);
}
Hello world