Skip to content

Commit

Permalink
mut-global utility
Browse files Browse the repository at this point in the history
  • Loading branch information
devrandom committed Sep 24, 2024
1 parent dbd6513 commit 7754bbb
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions lightning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ regex = { version = "1.5.6", optional = true }
backtrace = { version = "0.3", optional = true }

libm = { version = "0.2", default-features = false }
delegate = "0.12.0"

[dev-dependencies]
regex = "1.5.6"
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub(crate) mod fuzz_wrappers;
#[macro_use]
pub mod ser_macros;

#[cfg(feature = "std")]
pub mod mut_global;

pub mod errors;
pub mod ser;
pub mod message_signing;
Expand Down
67 changes: 67 additions & 0 deletions lightning/src/util/mut_global.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! A settable global variable.
//!
//! Used for testing purposes only.

use std::sync::Mutex;

/// A global variable that can be set exactly once.
pub struct MutGlobal<T> {
value: Mutex<Option<T>>,
default_fn: fn() -> T,
}

impl<T: Clone> MutGlobal<T> {
/// Create a new `MutGlobal` with no value set.
pub const fn new(default_fn: fn() -> T) -> Self {
Self { value: Mutex::new(None), default_fn }
}

/// Set the value of the global variable.
///
/// Ignores any attempt to set the value more than once.
pub fn set(&self, value: T) {
let mut lock = self.value.lock().unwrap();
*lock = Some(value);
}

/// Get the value of the global variable.
///
/// # Panics
///
/// Panics if the value has not been set.
pub fn get(&self) -> T {
let mut lock = self.value.lock().unwrap();
if let Some(value) = &*lock {
value.clone()
} else {
let value = (self.default_fn)();
*lock = Some(value.clone());
value
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test() {
let v = MutGlobal::<u8>::new(|| 0);
assert_eq!(v.get(), 0);
v.set(42);
assert_eq!(v.get(), 42);
v.set(43);
assert_eq!(v.get(), 43);
}

static G: MutGlobal<u8> = MutGlobal::new(|| 0);

#[test]
fn test_global() {
G.set(42);
assert_eq!(G.get(), 42);
G.set(43);
assert_eq!(G.get(), 43);
}
}

0 comments on commit 7754bbb

Please sign in to comment.