wp_error/error_handling/
strategy.rs1use orion_error::ErrStrategy;
2use serde::{Deserialize, Serialize};
3use std::{
4 fmt::Formatter,
5 sync::atomic::{AtomicU8, Ordering},
6};
7use wp_log::{error_ctrl, warn_ctrl};
8
9pub enum ErrorHandlingStrategy {
10 FixRetry,
11 Tolerant,
12 Throw,
13 Ignore,
14 Terminate,
15}
16
17impl From<ErrStrategy> for ErrorHandlingStrategy {
18 fn from(value: ErrStrategy) -> Self {
19 match value {
20 ErrStrategy::Retry => ErrorHandlingStrategy::FixRetry,
21 ErrStrategy::Ignore => ErrorHandlingStrategy::Ignore,
22 ErrStrategy::Throw => ErrorHandlingStrategy::Throw,
23 }
24 }
25}
26
27static ROBUST_MODE: AtomicU8 = AtomicU8::new(0);
28pub fn sys_robust_mode() -> RobustnessMode {
31 match ROBUST_MODE.load(Ordering::SeqCst) {
32 0 => RobustnessMode::Debug,
33 1 => RobustnessMode::Normal,
34 2 => RobustnessMode::Strict,
35 _ => unreachable!("Invalid robustness mode"),
36 }
37}
38
39pub fn switch_sys_robust_mode(mode: RobustnessMode) -> RobustnessMode {
40 let old = sys_robust_mode();
41 let new_mode = match mode {
42 RobustnessMode::Debug => 0,
43 RobustnessMode::Normal => 1,
44 RobustnessMode::Strict => 2,
45 };
46 warn_ctrl!("switch robust mode from {} to {}", old, mode);
48 ROBUST_MODE.store(new_mode, Ordering::SeqCst);
49 old
50}
51
52#[derive(Debug, Default, PartialEq, Deserialize, Serialize, Clone)]
53pub enum RobustnessMode {
54 #[default]
55 #[serde(rename = "debug")]
56 Debug,
57 #[serde(rename = "normal")]
58 Normal,
59 #[serde(rename = "strict")]
60 Strict,
61}
62
63impl From<&str> for RobustnessMode {
64 fn from(s: &str) -> Self {
65 match s {
66 "debug" => RobustnessMode::Debug,
67 "normal" => RobustnessMode::Normal,
68 "strict" => RobustnessMode::Strict,
69 other => {
70 error_ctrl!("unknown robust mode '{}', fallback to 'debug'", other);
72 RobustnessMode::Debug
73 }
74 }
75 }
76}
77
78impl std::fmt::Display for RobustnessMode {
79 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80 match self {
81 RobustnessMode::Debug => write!(f, "debug"),
82 RobustnessMode::Normal => write!(f, "normal"),
83 RobustnessMode::Strict => write!(f, "strict"),
84 }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn test_robustness_mode_default() {
94 let mode = RobustnessMode::default();
95 assert_eq!(mode, RobustnessMode::Debug);
96 }
97
98 #[test]
99 fn test_robustness_mode_from_str_debug() {
100 let mode = RobustnessMode::from("debug");
101 assert_eq!(mode, RobustnessMode::Debug);
102 }
103
104 #[test]
105 fn test_robustness_mode_from_str_normal() {
106 let mode = RobustnessMode::from("normal");
107 assert_eq!(mode, RobustnessMode::Normal);
108 }
109
110 #[test]
111 fn test_robustness_mode_from_str_strict() {
112 let mode = RobustnessMode::from("strict");
113 assert_eq!(mode, RobustnessMode::Strict);
114 }
115
116 #[test]
117 fn test_robustness_mode_from_str_unknown() {
118 let mode = RobustnessMode::from("unknown");
119 assert_eq!(mode, RobustnessMode::Debug); }
121
122 #[test]
123 fn test_robustness_mode_display() {
124 assert_eq!(RobustnessMode::Debug.to_string(), "debug");
125 assert_eq!(RobustnessMode::Normal.to_string(), "normal");
126 assert_eq!(RobustnessMode::Strict.to_string(), "strict");
127 }
128
129 #[test]
130 fn test_robustness_mode_serde() {
131 let json = "\"debug\"";
132 let mode: RobustnessMode = serde_json::from_str(json).unwrap();
133 assert_eq!(mode, RobustnessMode::Debug);
134
135 let json = "\"normal\"";
136 let mode: RobustnessMode = serde_json::from_str(json).unwrap();
137 assert_eq!(mode, RobustnessMode::Normal);
138
139 let json = "\"strict\"";
140 let mode: RobustnessMode = serde_json::from_str(json).unwrap();
141 assert_eq!(mode, RobustnessMode::Strict);
142 }
143
144 #[test]
145 fn test_robustness_mode_serialize() {
146 assert_eq!(
147 serde_json::to_string(&RobustnessMode::Debug).unwrap(),
148 "\"debug\""
149 );
150 assert_eq!(
151 serde_json::to_string(&RobustnessMode::Normal).unwrap(),
152 "\"normal\""
153 );
154 assert_eq!(
155 serde_json::to_string(&RobustnessMode::Strict).unwrap(),
156 "\"strict\""
157 );
158 }
159
160 #[test]
161 fn test_robustness_mode_clone() {
162 let mode = RobustnessMode::Normal;
163 let cloned = mode.clone();
164 assert_eq!(mode, cloned);
165 }
166
167 #[test]
168 fn test_error_handling_strategy_from_err_strategy() {
169 let retry: ErrorHandlingStrategy = ErrStrategy::Retry.into();
170 matches!(retry, ErrorHandlingStrategy::FixRetry);
171
172 let ignore: ErrorHandlingStrategy = ErrStrategy::Ignore.into();
173 matches!(ignore, ErrorHandlingStrategy::Ignore);
174
175 let throw: ErrorHandlingStrategy = ErrStrategy::Throw.into();
176 matches!(throw, ErrorHandlingStrategy::Throw);
177 }
178}