Skip to main content

chromiumoxide/handler/
httpfuture.rs

1use crate::handler::commandfuture::CommandFuture;
2use crate::handler::sender::PageSender;
3use crate::handler::target_message_future::TargetMessageFuture;
4use crate::{ArcHttpRequest, Result};
5use chromiumoxide_types::Command;
6use futures_util::future::{Fuse, FusedFuture};
7use futures_util::FutureExt;
8use pin_project_lite::pin_project;
9use std::future::Future;
10use std::pin::Pin;
11use std::task::{Context, Poll};
12
13type ArcRequest = ArcHttpRequest;
14
15pin_project! {
16    pub struct HttpFuture<T: Command> {
17        #[pin]
18        command: Fuse<CommandFuture<T>>,
19        #[pin]
20        navigation: TargetMessageFuture<ArcHttpRequest>,
21    }
22}
23
24impl<T: Command> HttpFuture<T> {
25    pub fn new(
26        sender: PageSender,
27        command: CommandFuture<T>,
28        request_timeout: std::time::Duration,
29    ) -> Self {
30        Self {
31            command: command.fuse(),
32            navigation: TargetMessageFuture::<T>::wait_for_navigation(sender, request_timeout),
33        }
34    }
35}
36
37impl<T> Future for HttpFuture<T>
38where
39    T: Command,
40{
41    type Output = Result<ArcRequest>;
42
43    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
44        let mut this = self.project();
45
46        // 1. First complete command request future
47        // 2. Switch polls navigation
48        if this.command.is_terminated() {
49            this.navigation.poll(cx)
50        } else {
51            match this.command.poll(cx) {
52                Poll::Ready(Ok(_command_response)) => {
53                    // Command succeeded — reset the navigation timer so it
54                    // gets a full request_timeout from NOW, not from when
55                    // HttpFuture was constructed, then immediately start
56                    // polling navigation (avoids a full wake round-trip).
57                    this.navigation.as_mut().reset_deadline();
58                    this.navigation.poll(cx)
59                }
60                Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
61                Poll::Pending => Poll::Pending,
62            }
63        }
64    }
65}