posemesh_node_registration/
persist.rs1use anyhow::{anyhow, Result};
2use std::sync::{Mutex, MutexGuard, OnceLock};
3
4#[derive(Default)]
5struct NodeSecretStore {
6 secret: Option<String>,
7}
8
9static NODE_SECRET_STORE: OnceLock<Mutex<NodeSecretStore>> = OnceLock::new();
10
11fn node_secret_store() -> &'static Mutex<NodeSecretStore> {
12 NODE_SECRET_STORE.get_or_init(|| Mutex::new(NodeSecretStore::default()))
13}
14
15fn lock_node_secret_store() -> Result<MutexGuard<'static, NodeSecretStore>> {
16 node_secret_store()
17 .lock()
18 .map_err(|_| anyhow!("node secret store poisoned"))
19}
20
21pub fn write_node_secret(secret: &str) -> Result<()> {
23 let mut store = lock_node_secret_store()?;
24 store.secret = Some(secret.to_owned());
25 Ok(())
26}
27
28pub fn read_node_secret() -> Result<Option<String>> {
30 let store = lock_node_secret_store()?;
31 Ok(store.secret.clone())
32}
33
34pub fn clear_node_secret() -> Result<()> {
36 let mut store = lock_node_secret_store()?;
37 store.secret = None;
38 Ok(())
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn write_and_read_roundtrip() {
47 clear_node_secret().unwrap();
48
49 write_node_secret("first").unwrap();
50 let got = read_node_secret().unwrap();
51 assert_eq!(got.as_deref(), Some("first"));
52
53 write_node_secret("second").unwrap();
54 let got2 = read_node_secret().unwrap();
55 assert_eq!(got2.as_deref(), Some("second"));
56
57 clear_node_secret().unwrap();
58 assert!(read_node_secret().unwrap().is_none());
59 }
60}