use serde::Serialize; use std::sync::{OnceLock, RwLock}; #[derive(Debug, Clone, Serialize)] pub struct InitErrorPayload { pub path: String, pub error: String, } static INIT_ERROR: OnceLock>> = OnceLock::new(); fn cell() -> &'static RwLock> { INIT_ERROR.get_or_init(|| RwLock::new(None)) } #[allow(dead_code)] pub fn set_init_error(payload: InitErrorPayload) { #[allow(clippy::unwrap_used)] if let Ok(mut guard) = cell().write() { *guard = Some(payload); } } pub fn get_init_error() -> Option { cell().read().ok()?.clone() } // ============================================================ // 迁移结果状态 // ============================================================ static MIGRATION_SUCCESS: OnceLock> = OnceLock::new(); fn migration_cell() -> &'static RwLock { MIGRATION_SUCCESS.get_or_init(|| RwLock::new(false)) } pub fn set_migration_success() { if let Ok(mut guard) = migration_cell().write() { *guard = true; } } /// 获取并消费迁移成功状态(只返回一次 true,之后返回 false) pub fn take_migration_success() -> bool { if let Ok(mut guard) = migration_cell().write() { let val = *guard; *guard = false; val } else { false } } #[cfg(test)] mod tests { use super::*; #[test] fn init_error_roundtrip() { let payload = InitErrorPayload { path: "/tmp/config.json".into(), error: "broken json".into(), }; set_init_error(payload.clone()); let got = get_init_error().expect("should get payload back"); assert_eq!(got.path, payload.path); assert_eq!(got.error, payload.error); } }