Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Allow Vec of custom type to be joined with &str

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In order for a list of Ts 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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading