How can I get the body from the closure


use std::io::{self, Write};
use std::sync::{Arc, Mutex};
use hyper::{Chunk, Client, Error, Uri};
use hyper::rt::{self, Future, Stream};

pub fn run() {

    let fut = do_request().map(move |body|{
        println!("{}", body);
    }).map_err(|err|{
        println!("{:?}", err);
    });

    rt::run(fut);
//  println!("{:?}", body);
//  how can I get the body from the closure

    println!("lalala");
    println!("lalala");
    println!("lalala");
    println!("lalala")
}

fn do_request() -> impl Future<Item=String, Error=hyper::error::Error> {
    let client = Client::new();
    client
        .get(Uri::from_static("http://httpbin.org/ip"))
        .and_then(|res| {
            println!("status: {}", res.status());
            res.into_body().concat2()
        })
        .and_then(|body| {
            let s = ::std::str::from_utf8(&body).expect("httpbin sends utf-8 JSON");
            Ok(s.to_string())
        })
        .map_err(|err| {
            err
        })
}

You cannot. After calling hyper::rt::run, you are passing ownership over whole fut, and when the call is done, probably anything it was holding doesn’t exist anymore. You need to handle whole your response processing in your future continuations like map or inspect, or just via async/.await syntax.

In general, you could use something like block_on instead of run to block the caller until the future completes. But I haven’t tried that with hyper specifically.

https://docs.rs/tokio/0.1.22/tokio/runtime/current_thread/struct.Runtime.html#method.block_on

However, if you’re going to use futures/async calls in a blocking fashion, that makes them mostly useless. If you want blocking code, you can use a blocking library instead of putting effort to spawn things asynchronously and then undo the asynchronous behavior: