Здравствуйте.
Продолжаю пытаться для обучения сделать OAuth авторизацию гугла. Сначала код
enum RequestFinished {Ready, NotReady}
impl Future for RequestFinished {
type Item = ();
type Error = ();
fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
match self {
RequestFinished::Ready => Ok(Ready(())),
RequestFinished::NotReady => Ok(NotReady)
}
}
}
fn retrieve_auth() {
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let (sender, receiver) = futures::sync::oneshot::channel::<()>();
let sender = RefCell::new(Some(sender));
let waiter: &mut RefCell<RequestFinished> = &mut RefCell::new(RequestFinished::NotReady);
let proc = move || {
let res = service_fn_ok(got_response);
sender.borrow_mut().take().unwrap().send(());
waiter.replace(RequestFinished::Ready); <--------------------
res
};
let server = Server::bind(&addr)
.serve(proc)
.with_graceful_shutdown(receiver)
.map_err(|e| eprintln!("server error: {}", e));
hyper::rt::run(server);
let uri = Url::parse_with_params(GOOGLE_AUTH_URL, [
("client_id", CLIENT_ID),
("redirect_uri", "http://[::1]:3000"),
("response_type", "code"),
("scope", "https://www.googleapis.com/auth/drive")
].iter());
let https = HttpsConnector::new(1).unwrap();
let res = Client::new()
.get(uri.unwrap().as_str().parse::<Uri>().unwrap());
waiter.into_inner().wait(); <--------------------
}
Сейчас он не компилируются по причине двойного заимствования waiter. И у меня никаких идей как это исправить. Ведь, по сути, нужна одна и та же Future в 2-х разных потока, ещё и во втором потке в качестве значения!
Как вариант, я думал использовать каналы, по аналогии, как сделано с sender-ом. Но для этого нужно создавать ещё один поток в Tokio - слишком тяжело, по-моему.
Подскажите, как проще реализовать паузу до возврата значения из потока?
Спасибо.