Annotated version
1use std::time::Duration;
2
3use color_eyre::eyre;
4
5struct Deferred<T: FnOnce()> {
6 task: Option<T>,
7}
8
9impl<T: FnOnce()> Deferred<T> {
10 fn abort(&mut self) {
11 println!("I AM ABORTING");
12 self.task.take();
13 }
14}
15
16impl<T: FnOnce()> Drop for Deferred<T> {
17 fn drop(&mut self) {
18 if let Some(task) = self.task.take() {
19 task();
20 }
21 }
22}
23
24fn defer<T: FnOnce()>(f: T) -> Deferred<T> {
25 Deferred { task: Some(f) }
26}
27
28async fn send_request(url: &str) -> eyre::Result<()> {
29 let mut finish = defer(|| println!("I am done here")); // this pattern is amazing, this is only called when there is no timeout
30 // otherwise abort is called
31 let request = reqwest::get(url);
32 tokio::select! {
33 response = request => {
34 let response = response?;
35 let body = response.text().await?;
36 println!("{:?}", &body[..20]);
37 }
38 _ = tokio::time::sleep(Duration::from_millis(1000)) => {
39 finish.abort();
40 return Err(eyre::eyre!("timeout"))
41 }
42 }
43 Ok(())
44}
45
46#[tokio::main]
47async fn main() {
48 println!("MAKING REQ");
49 send_request("https://www.google.com").await.unwrap();
50}
51