Hyper timeout implementation

Hi, I have use hyper-timeout crate to have custom timeout with hyper 0.11 but since I upgrade to hyper 0.12 I struggle to have this function implemented in my project.

I tried to use the example provide here but I can't get rid of the "expected struct std::io::Error, found struct hyper::Error error.
I tried to map_err to a custom error and I get an errors than even more elusive to me.

//main.rs

extern crate hyper;
extern crate futures;
extern crate tokio_core;

use std::error::Error;
use std::io;
use std::time::Duration;

use hyper::Client;
use hyper::client::HttpConnector;
use tokio_core::reactor::{Core, Timeout};
use futures::{Future, Stream};

fn main() -> Result<(), Box<Error>>  {
   	let mut core = Core::new()?;
	let client = Client::builder().build(HttpConnector::new(4));
	let timeout = Timeout::new(Duration::from_secs(30), &core.handle())?.then(|_| Err(io::Error::new(io::ErrorKind::TimedOut, "our timeout")));
	// set up our client request
	let future_body = client.get("http://127.0.0.1".parse()?).and_then(|res| {
	    res.body().fold(Vec::new(), |mut vec, chunk| {
		vec.extend_from_slice(&chunk);
		Ok(vec)
	    })
	});
	let work = future_body.select(timeout).then(|result| {
	    match result { 
		Ok(body) => {
		},
		Err(e) => {
		}
	    }
	});
	core.handle().spawn(work);

	Ok(())
}

//Cargo.toml
[dependencies]
futures = "0.1"
hyper = "0.12"
tokio-core = "0.1"

Edit:
Sorry for the not styling the code but I can't find the option to do so.

One way is to use select2

Thanks both of you.
I got something that seems to work: How to set timeout for HTTP request with hyper, tokio and futures in Rust? - Stack Overflow

let response: Mutex<(StatusCode, HeaderMap)> =
		Mutex::new((StatusCode::from_u16(501).unwrap(), HeaderMap::new()));
	let work = client
		.request(req)
		.and_then(|res| {
			match response.lock() {
				Ok(mut response) => {
					response.0 = res.status();
					response.1 = res.headers().clone()
				}
				Err(_) => {}
			}
			res.into_body().fold(Vec::new(), |mut vec, chunk| {
				vec.extend(&chunk[..]);
				futures::future::ok::<_, HyperError>(vec)
			})
		})
		.select2(Timeout::new(Duration::from_secs(timeout), &core.handle())?)
		.then(|result| match result {
			Ok(Either::A((got, _timeout))) => {
				let headers;
				let status;
				match response.lock() {
					Ok(res) => {
						status = res.0;
						headers = res.1.clone();
					}
					Err(_) => {
						status = StatusCode::from_u16(501).unwrap();
						headers = HeaderMap::new();
					}
				}
				Ok(HttpResponse {
					status,
					body: got,
					headers,
					uri: None,
				})
			}
			Ok(Either::B((_timeout_error, _get))) => {
				return Err(MyError::new(-1, "Client timed out while connecting"));
			}
			Err(Either::A((get_error, _timeout))) => Err(MyError::from(get_error)),
			Err(Either::B((timeout_error, _get))) => Err(MyError::from(timeout_error)),
		});l

I have to use a Mutex and recreate an error each time, I don't think it's the best way to do it. I tried to Box the errors but got mismatch expect type error. Tried to return tuple of body response and header response select2 complains about not implemented trait. If someone can come with better implementation.

Here my previous implementation

let work = client.request(req)
		.and_then(|res| {
	        let response = (res.status(), res.headers().clone());
		res.into_body().fold(Vec::new(), |mut v, chunk| {
				v.extend(&chunk[..]);
				futures::future::ok::<_, HyperError>(v)
			}).and_then(|chunks| {
				futures::future::ok::<_, HyperError>(Ok(HttpResponse {
					status: response.0,
					body: chunks.to_vec(),
					headers: response.1,
					uri: None,
				}))
			})
		})