diff --git a/fish-rust/src/common.rs b/fish-rust/src/common.rs new file mode 100644 index 000000000..e5942ba2a --- /dev/null +++ b/fish-rust/src/common.rs @@ -0,0 +1,33 @@ +use std::mem; + +/// A scoped manager to save the current value of some variable, and optionally set it to a new +/// value. When dropped, it restores the variable to its old value. +/// +/// This can be handy when there are multiple code paths to exit a block. +pub struct ScopedPush<'a, T> { + var: &'a mut T, + saved_value: Option, +} + +impl<'a, T> ScopedPush<'a, T> { + pub fn new(var: &'a mut T, new_value: T) -> Self { + let saved_value = mem::replace(var, new_value); + + Self { + var, + saved_value: Some(saved_value), + } + } + + pub fn restore(&mut self) { + if let Some(saved_value) = self.saved_value.take() { + *self.var = saved_value; + } + } +} + +impl<'a, T> Drop for ScopedPush<'a, T> { + fn drop(&mut self) { + self.restore() + } +} diff --git a/fish-rust/src/lib.rs b/fish-rust/src/lib.rs index fd1203b4f..11b39e648 100644 --- a/fish-rust/src/lib.rs +++ b/fish-rust/src/lib.rs @@ -4,6 +4,7 @@ #![allow(clippy::needless_return)] #![allow(clippy::manual_is_ascii_check)] +mod common; mod fd_readable_set; mod fds; #[allow(rustdoc::broken_intra_doc_links)]