[SOLVED] How to force closure to take ownership of String?


#1

With crate Curl, I want to write received data in String.

I do this, Result data of write_function(…) is &[u8]

let html: String = String::new();
let mut easy = Easy::new();
easy.write_function(|data| {
        html = String::from_utf8(Vec::from(data)).unwrap();        
        Ok(data.len())
}).unwrap();

I have this error

Compiling htmlparser v0.0.1 (file:///C:/Users/RUST%20Project/htmlparser)
src\main.rs:37:25: 37:31 error: closure may outlive the current function, but it borrows html, which is owned by the current function [E0373]
src\main.rs:37 easy.write_function(|data| {
^~~~~~
src\main.rs:37:25: 37:31 help: run rustc --explain E0373 to see a detailed explanation
src\main.rs:38:9: 38:13 note: html is borrowed here
src\main.rs:38 html = String::from_utf8(Vec::from(data)).unwrap();
^~~~
src\main.rs:37:25: 37:31 help: to force the closure to take ownership of html (and any other referenced variables), use the move keyword, as shown:
src\main.rs: easy.write_function(move |data| {

But I can’t do move |data|, String does not implement the Copy trait.

How can I write received data into String?


#2

You probably don’t want want the closure to take ownership of the string, because you want to use it afterwards, I guess.

The problem is that the closure can’t borrow captured variable, because write_function requires 'static bound on the closure. This problem is explained with examples in the documentation for write_function. The solution uses a transfer method. It should work for you.


#3

Thank for your help, you are right.
Here is solution with the use of transfer method.

    let mut html: String = String::new();
    {
        let mut transfer = easy.transfer();
        transfer.write_function(|data| {
            html.push_str(str::from_utf8(data).unwrap());          
            Ok(data.len())
        }).unwrap(); 

        transfer.perform().unwrap();
    }