Skip to content

Commit 7d35171

Browse files
committed
mut-global utility
1 parent f302e2e commit 7d35171

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

lightning/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ backtrace = { version = "0.3", optional = true }
5050

5151
core2 = { version = "0.3.0", optional = true, default-features = false }
5252
libm = { version = "0.2", optional = true, default-features = false }
53+
delegate = "0.12.0"
5354

5455
[dev-dependencies]
5556
regex = "1.5.6"

lightning/src/util/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pub(crate) mod fuzz_wrappers;
1515
#[macro_use]
1616
pub mod ser_macros;
1717

18+
pub mod mut_global;
19+
1820
pub mod errors;
1921
pub mod ser;
2022
pub mod message_signing;

lightning/src/util/mut_global.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//! An unsafe global variable that can be set exactly once.
2+
//!
3+
//! Used for testing purposes only.
4+
5+
use std::sync::Mutex;
6+
7+
/// A global variable that can be set exactly once.
8+
pub struct MutGlobal<T> {
9+
value: Mutex<Option<T>>,
10+
}
11+
12+
impl<T: Clone> MutGlobal<T> {
13+
/// Create a new `MutGlobal` with no value set.
14+
pub const fn new() -> Self {
15+
Self {
16+
value: Mutex::new(None),
17+
}
18+
}
19+
20+
/// Set the value of the global variable.
21+
///
22+
/// Ignores any attempt to set the value more than once.
23+
pub fn set(&self, value: T) {
24+
let mut lock = self.value.lock().unwrap();
25+
if lock.is_none() {
26+
*lock = Some(value);
27+
}
28+
}
29+
30+
/// Get the value of the global variable.
31+
///
32+
/// # Panics
33+
///
34+
/// Panics if the value has not been set.
35+
pub fn get(&self) -> T {
36+
self.value
37+
.lock()
38+
.unwrap()
39+
.clone()
40+
.expect("not set")
41+
}
42+
43+
/// Whether a value was set
44+
pub fn is_set(&self) -> bool {
45+
self.value.lock().unwrap().is_some()
46+
}
47+
}
48+
49+
#[cfg(test)]
50+
mod tests {
51+
use super::*;
52+
53+
#[test]
54+
fn test() {
55+
let v = MutGlobal::<u8>::new();
56+
assert!(!v.is_set());
57+
v.set(42);
58+
assert_eq!(v.get(), 42);
59+
v.set(43);
60+
assert_eq!(v.get(), 42);
61+
}
62+
63+
static G: MutGlobal<u8> = MutGlobal::new();
64+
65+
#[test]
66+
fn test_global() {
67+
assert!(!G.is_set());
68+
G.set(42);
69+
assert_eq!(G.get(), 42);
70+
G.set(43);
71+
assert_eq!(G.get(), 42);
72+
}
73+
}

0 commit comments

Comments
 (0)