Skip to content

Instantly share code, notes, and snippets.

@zeroows
Created November 14, 2024 22:42
Show Gist options
  • Save zeroows/0348ed6e12a53acb7383b693180c92ec to your computer and use it in GitHub Desktop.
Save zeroows/0348ed6e12a53acb7383b693180c92ec to your computer and use it in GitHub Desktop.
Rust defer
struct Deferred<T: FnOnce()> {
task: Option<T>,
}
impl<T: FnOnce()> Deferred<T> {
fn abort(&mut self) {
self.task.take();
}
}
impl<T: FnOnce()> Drop for Deferred<T> {
fn drop(&mut self) {
if let Some(task) = self.task.take() {
task();
}
}
}
fn defer<T: FnOnce()>(f: T) -> Deferred<T> {
Deferred { task: Some(f) }
}
@zeroows
Copy link
Author

zeroows commented Nov 14, 2024

and to use it

async fn send_request(
    url: &str,
    metrics: &mut Metrics
) -> Result<String> {
    let mut finish = defer(|| metrics.requests += 1);

    let request = reqwest::get(url);
    tokio::select! {
        response = request => {
            let response = response?;
            let body = response.text().await?;
            Ok(body)
        }
        _ = tokio::time::sleep(Duration::from_millis(2500)) => {
            finish.abort();
            Err(anyhow::anyhow!("timeout"))
        }
    }
}

source

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment