From 03c64a1a21571961e66828e19f214329dc7d70e5 Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Wed, 28 Feb 2024 19:55:05 +0300 Subject: [PATCH] chore: ScopeGuard --- src/util.rs | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/util.rs b/src/util.rs index 5ed1afd60a..2b69578896 100644 --- a/src/util.rs +++ b/src/util.rs @@ -471,18 +471,8 @@ pub fn prompt_password(prompt: &str) -> Result<String, std::io::Error> { let tty_fd = tty.as_raw_fd(); let tcattr_old = tcgetattr(tty_fd)?; - // Restore old terminal settings when `_d` is dropped - let _d = Defer(Some(|| { - tcsetattr(tty_fd, TCSADRAIN, &tcattr_old).unwrap_or(()) - })); - struct Defer<F: FnOnce()>(Option<F>); - impl<F: FnOnce()> Drop for Defer<F> { - fn drop(&mut self) { - if let Some(f) = self.0.take() { - f() - } - } - } + // Restore old terminal settings when `_guard` is dropped + let _guard = on_scope_exit(|| tcsetattr(tty_fd, TCSADRAIN, &tcattr_old).unwrap_or(())); // Disable echo while prompting a password let mut tcattr_new = tcattr_old.clone(); @@ -718,6 +708,40 @@ impl<T> std::ops::DerefMut for NoYieldsRefMut<'_, T> { } } +//////////////////////////////////////////////////////////////////////////////// +// ScopeGuard +//////////////////////////////////////////////////////////////////////////////// +// TODO: this one is copied from tarantool-module, it should instead be export from there + +#[derive(Debug)] +#[must_use = "The callback is invoked when the `ScopeGuard` is dropped"] +pub struct ScopeGuard<F> +where + F: FnOnce(), +{ + cb: Option<F>, +} + +impl<F> Drop for ScopeGuard<F> +where + F: FnOnce(), +{ + #[inline(always)] + fn drop(&mut self) { + if let Some(cb) = self.cb.take() { + cb() + } + } +} + +#[inline(always)] +pub fn on_scope_exit<F>(cb: F) -> ScopeGuard<F> +where + F: FnOnce(), +{ + ScopeGuard { cb: Some(cb) } +} + //////////////////////////////////////////////////////////////////////////////// // ... //////////////////////////////////////////////////////////////////////////////// -- GitLab