chromiumoxide/handler/
httpfuture.rs1use futures_util::future::{Fuse, FusedFuture};
2use futures_util::FutureExt;
3use pin_project_lite::pin_project;
4use std::future::Future;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7use tokio::sync::mpsc;
8
9use crate::handler::commandfuture::CommandFuture;
10use crate::handler::target::TargetMessage;
11use crate::handler::target_message_future::TargetMessageFuture;
12use crate::{ArcHttpRequest, Result};
13use chromiumoxide_types::Command;
14
15type ArcRequest = ArcHttpRequest;
16
17pin_project! {
18 pub struct HttpFuture<T: Command> {
19 #[pin]
20 command: Fuse<CommandFuture<T>>,
21 #[pin]
22 navigation: TargetMessageFuture<ArcHttpRequest>,
23 }
24}
25
26impl<T: Command> HttpFuture<T> {
27 pub fn new(
28 sender: mpsc::Sender<TargetMessage>,
29 command: CommandFuture<T>,
30 request_timeout: std::time::Duration,
31 ) -> Self {
32 Self {
33 command: command.fuse(),
34 navigation: TargetMessageFuture::<T>::wait_for_navigation(sender, request_timeout),
35 }
36 }
37}
38
39impl<T> Future for HttpFuture<T>
40where
41 T: Command,
42{
43 type Output = Result<ArcRequest>;
44
45 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
46 let this = self.project();
47
48 if this.command.is_terminated() {
51 this.navigation.poll(cx)
52 } else {
53 match this.command.poll(cx) {
54 Poll::Ready(Ok(_command_response)) => {
55 this.navigation.reset_deadline();
59 cx.waker().wake_by_ref();
60 Poll::Pending
61 }
62 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
63 Poll::Pending => Poll::Pending,
64 }
65 }
66 }
67}