anchor_coverage/util/
var_guard.rs

1// smoelius: `VarGuard` is based on a struct of the same name from Clippy's source code. The `set`
2// method was modified to accept an `Option` so that variables could be cleared. Also, `unsafe`
3// annotations were added to make the struct compile with Rust Edition 2024. See:
4// https://github.com/rust-lang/rust-clippy/blob/c51472b4b09d22bdbb46027f08be54c4b285a725/tests/compile-test.rs#L267-L289
5
6use std::{
7    env::{remove_var, set_var, var_os},
8    ffi::{OsStr, OsString},
9    marker::PhantomData,
10};
11
12/// Restores an env var on drop
13#[must_use]
14pub struct VarGuard<T = OsString> {
15    key: &'static str,
16    value: Option<OsString>,
17    _phantom: PhantomData<T>,
18}
19
20impl<T: AsRef<OsStr>> VarGuard<T> {
21    pub fn set(key: &'static str, val: Option<T>) -> Self {
22        let value = var_os(key);
23        if let Some(val) = val {
24            unsafe { set_var(key, val) };
25        } else {
26            unsafe { remove_var(key) };
27        }
28        Self {
29            key,
30            value,
31            _phantom: PhantomData,
32        }
33    }
34}
35
36impl<T> Drop for VarGuard<T> {
37    fn drop(&mut self) {
38        match self.value.as_deref() {
39            None => unsafe { remove_var(self.key) },
40            Some(value) => unsafe { set_var(self.key, value) },
41        }
42    }
43}