-5

I have a Vec<&[u8]> that I want to convert to a String like this:

let rfrce: Vec<&[u8]> = rec.alleles();

for r in rfrce {
    // create new String from rfrce
}

I tried this but it is not working since only converting u8 to char is possible, but [u8] to char is not:

let rfrce = rec.alleles();

let mut str = String::from("");

for r in rfrce {
    str.push(*r as char);
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
fxwiegand
  • 1
  • 2
  • 1
    What's the intended logic for this conversion ? What's in those `[u8]` ? – Denys Séguret Jun 19 '19 at 09:22
  • for such type of questions I'm using Rust community IRC channel in freenode (chat.freenode.net port:6697, channel name: ##rust). They give me quick working answers – num8er Jun 19 '19 at 10:04

2 Answers2

4

Because r is an array of u8, you need to convert it to a valid &str and use push_str method of String.

use std::str;

fn main() {
    let rfrce = vec![&[65,66,67], &[68,69,70]];

    let mut str = String::new();

    for r in rfrce {
        str.push_str(str::from_utf8(r).unwrap());
    }

    println!("{}", str);
}

Rust Playground

Leśny Rumcajs
  • 2,259
  • 2
  • 17
  • 33
  • thank you, i discovered that my Vec<&[u8]> looks like [[67, 84], [71, 84], [67]] or as a string: CTGTC. I want to split the vec in to 3 strings: str1 = CT, str2 = GT and str3 = C. – fxwiegand Jun 19 '19 at 10:03
  • 1
    With the error handling: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8f91418dbcd5448038d5c91f34da5952 – Boiethios Jun 19 '19 at 10:05
  • @fxwiegand You can do it with `Vec<&str>` : [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=0105b5655f23200acd7d58758728a767) – Leśny Rumcajs Jun 19 '19 at 10:18
1

I'd go with TryFrom<u32>:

fn to_string(v: &[&[u8]]) -> Result<String, std::char::CharTryFromError> {
    /// Transform a &[u8] to an UTF-8 codepoint
    fn su8_to_u32(s: &[u8]) -> Option<u32> {
        if s.len() > 4 {
            None
        } else {
            let shift = (0..=32).step_by(8);
            let result = s.iter().rev().cloned().zip(shift).map(|(u, shift)| (u as u32) << shift).sum();
            Some(result)
        }
    }

    use std::convert::TryFrom;

    v.iter().map(|&s| su8_to_u32(s)).try_fold(String::new(), |mut s, u| {
        let u = u.unwrap(); //TODO error handling
        s.push(char::try_from(u)?);
        Ok(s)
    })
}

fn main() {
    let rfrce: Vec<&[u8]> = vec![&[48][..], &[49][..], &[50][..], &[51][..]];
    assert_eq!(to_string(&rfrce), Ok("0123".into()));

    let rfrce: Vec<&[u8]> = vec![&[0xc3, 0xa9][..]]; // https://www.utf8icons.com/character/50089/utf-8-character
    assert_eq!(to_string(&rfrce), Ok("쎩".into()));

}
Boiethios
  • 38,438
  • 19
  • 134
  • 183