Search code examples
rusthyper

Append new line character to Hyper Body struct


I am trying to modify the response that gets returned back from the echo example when using hyper. Their code sample is here.

The only thing that is different in my code is that I am trying to append a new line character to the end of my collection

(&Method::POST, "/echo/uppercase") => {
  let newLine = "\n".as_bytes().to_vec();
  let m = req.into_body()
    .map_ok(|c| {
        c.iter()
        .map(|byte| byte.to_ascii_uppercase())
        .collect::<Vec<u8>>()
        .append(&mut newLine) <-- this line
    });

  *response.body_mut() = Body::wrap_stream(m);
},

The compiler is returning

*response.body_mut() = Body::wrap_stream(m);
                                         ^ the trait `std::convert::From<()>` is not implemented for `bytes::bytes::Bytes`

Does the append modify the type of the collection so that it is no longer considered a Future stream for the wrap_stream method?

Also is this the preferred way to append things to a Body struct in hyper?


Solution

  • The closure passed to map_ok() returns (), not the Vec<u8> you are expecting.

    This is because Vec::append(), which you use to append the newline, returns (), not the modified Vec.

    Simple solution: modify the closure to return the Vec<u8>:

    |c| {
        let mut v = c.iter()
            .map(|byte| byte.to_ascii_uppercase())
            .collect::<Vec<u8>>();
        v.append(&mut newline);
        v
    }
    

    Since a newline is a one-byte character, it might make more sense to just add it to the Vec directly:

    v.push(b'\n');
    

    This avoids the unnecessary allocation of the newline Vec for every request.