1use std::sync::OnceLock;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub enum UnsupportedOptionPolicy {
18 Ignore,
20 Warn,
23 Strict,
25}
26
27static POLICY: OnceLock<UnsupportedOptionPolicy> = OnceLock::new();
28
29pub fn set_unsupported_option_policy(policy: UnsupportedOptionPolicy) {
32 let _ = POLICY.set(policy);
33}
34
35pub fn unsupported_option_policy() -> UnsupportedOptionPolicy {
37 POLICY
38 .get()
39 .copied()
40 .unwrap_or(UnsupportedOptionPolicy::Warn)
41}
42
43pub fn report_unsupported(
48 backend: &str,
49 plot_type: &str,
50 option: &str,
51 collector: &mut Vec<String>,
52) {
53 let key = format!("{plot_type}.{option}");
54 if collector.contains(&key) {
55 return;
56 }
57
58 let policy = unsupported_option_policy();
59 match policy {
60 UnsupportedOptionPolicy::Ignore => {}
61 UnsupportedOptionPolicy::Warn | UnsupportedOptionPolicy::Strict => {
62 eprintln!("{backend}: `{option}` on {plot_type} not supported; ignored");
63 }
64 }
65 collector.push(key);
66}
67
68pub fn enforce_strict(backend: &str, collector: &[String]) {
71 if unsupported_option_policy() == UnsupportedOptionPolicy::Strict && !collector.is_empty() {
72 panic!(
73 "{backend}: unsupported options encountered in Strict mode:\n - {}",
74 collector.join("\n - ")
75 );
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_default_policy_is_warn() {
85 assert_eq!(unsupported_option_policy(), UnsupportedOptionPolicy::Warn);
88 }
89
90 #[test]
91 fn test_report_unsupported_deduplicates() {
92 let mut collector = Vec::new();
93 report_unsupported("test", "Scatter", "fill", &mut collector);
94 report_unsupported("test", "Scatter", "fill", &mut collector);
95 assert_eq!(collector.len(), 1);
96 }
97
98 #[test]
99 fn test_report_unsupported_different_options() {
100 let mut collector = Vec::new();
101 report_unsupported("test", "Scatter", "fill", &mut collector);
102 report_unsupported("test", "Scatter", "hover", &mut collector);
103 assert_eq!(collector.len(), 2);
104 }
105
106 #[test]
107 fn test_enforce_strict_with_empty_collector() {
108 enforce_strict("test", &[]);
110 }
111}