Is clone the best choice here?

I need to convert the Vec body from a websocket (tungstenite) response to a String. Because String::from_utf8 takes a value (takes ownership), I needed to call clone on the body:

    match connect("wss://...") {
        Ok((mut socket, response)) => {
            let body = String::from_utf8(response.body().clone().unwrap()).unwrap();

It just feels wrong to have to do this. Is there a better alternative, in this specific case?

You probably want into_body or into_parts, which allow you to get an owned Vec without cloning.

3 Likes

Changed to into_body().

Follow-up regarding methods like this:

    /// Consumes the response, returning just the body.
    ///
    /// # Examples
    ///
    /// ```
    /// # use http::Response;
    /// let response = Response::new(10);
    /// let body = response.into_body();
    /// assert_eq!(body, 10);
    /// ```
    #[inline]
    pub fn into_body(self) -> T {
        self.body
    }

How does the method "consume" the response? I don't understand what's happening here re: ownership...

self argument, without &, moves the whole object into method's body. Move means the caller loses access to it. Ownership is exclusive, so this guarantees that for this instance of self this variable is the only place where it exists, and there's no other way to access this object from anywhere else in the program.

Because this self has full exclusive access and full ownership, it is allowed to remove the body field, which is also exclusively owned here.

Rest of the self object will be automatically destroyed, because this function had the last and only way to access this object, and it didn't store or return it anywhere (it returned only the body object which will be kept alive)

1 Like

Ah yes, of course, it's the self (rather than &self or &mut self) - thanks for the reminder.

(Be away from Rust for a few months and the basics start to go.)