1use std::collections::HashMap;
31use std::sync::{Mutex, OnceLock};
32
33static DEPRECATION_CONFIG: OnceLock<Mutex<DeprecationConfig>> = OnceLock::new();
35
36#[derive(Debug, Clone)]
38pub struct DeprecationConfig {
39 pub show_warnings: bool,
41
42 pub warnings_as_errors: bool,
44
45 pub max_warning_count: usize,
47
48 pub warning_counts: HashMap<String, usize>,
50
51 pub current_version: String,
53}
54
55impl Default for DeprecationConfig {
56 fn default() -> Self {
57 Self {
58 show_warnings: true,
59 warnings_as_errors: false,
60 max_warning_count: 3,
61 warning_counts: HashMap::new(),
62 current_version: "0.1.0-beta.4".to_string(),
63 }
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
69pub enum DeprecationLevel {
70 Experimental,
72 Soft,
74 Hard,
76 Removed,
78}
79
80#[derive(Debug, Clone)]
82pub struct DeprecationInfo {
83 pub name: String,
85
86 pub since: String,
88
89 pub remove_in: Option<String>,
91
92 pub level: DeprecationLevel,
94
95 pub reason: String,
97
98 pub alternative: Option<String>,
100
101 pub migration_notes: Option<String>,
103}
104
105#[allow(dead_code)]
107pub fn init_deprecation_system() {
108 let _ = DEPRECATION_CONFIG.set(Mutex::new(DeprecationConfig::default()));
109}
110
111#[allow(dead_code)]
113pub fn configure_deprecation(config: DeprecationConfig) {
114 init_deprecation_system();
115 if let Ok(mut global_config) = DEPRECATION_CONFIG.get().unwrap().lock() {
116 *global_config = config;
117 }
118}
119
120#[allow(dead_code)]
122pub fn issue_deprecation_warning(info: &DeprecationInfo) {
123 init_deprecation_system();
124
125 if let Ok(mut config) = DEPRECATION_CONFIG.get().unwrap().lock() {
126 if !config.show_warnings {
127 return;
128 }
129
130 let count = config.warning_counts.entry(info.name.clone()).or_insert(0);
131 *count += 1;
132
133 if *count > config.max_warning_count {
134 return;
135 }
136
137 let warning_msg = format_deprecation_warning(info);
138
139 if config.warnings_as_errors {
140 panic!("Deprecation error: {warning_msg}");
141 } else {
142 eprintln!("Deprecation warning: {warning_msg}");
143 }
144 }
145}
146
147#[allow(dead_code)]
149fn format_deprecation_warning(info: &DeprecationInfo) -> String {
150 let mut msg = format!(
151 "Function '{}' is deprecated since v{}",
152 info.name, info.since
153 );
154
155 if let Some(remove_version) = &info.remove_in {
156 msg.push_str(&format!(" and will be removed in v{remove_version}"));
157 }
158
159 msg.push_str(&format!(": {}", info.reason));
160
161 if let Some(alternative) = &info.alternative {
162 msg.push_str(&format!(" Use '{alternative}' instead."));
163 }
164
165 if let Some(notes) = &info.migration_notes {
166 msg.push_str(&format!(" Migration notes: {notes}"));
167 }
168
169 msg
170}
171
172#[macro_export]
174macro_rules! deprecated_function {
175 (
176 name = $name:expr,
177 since = $since:expr,
178 reason = $reason:expr
179 $(, alternative = $alternative:expr)?
180 $(, remove_in = $remove_in:expr)?
181 $(, migration_notes = $notes:expr)?
182 $(, level = $level:expr)?
183 ) => {
184 {
185 use $crate::deprecation::{DeprecationInfo, DeprecationLevel, issue_deprecation_warning};
186
187 let info = DeprecationInfo {
188 name: $name.to_string(),
189 since: $since.to_string(),
190 remove_in: None $(.or(Some($remove_in.to_string())))?,
191 level: DeprecationLevel::Soft $(.max($level))?,
192 reason: $reason.to_string(),
193 alternative: None $(.or(Some($alternative.to_string())))?,
194 migration_notes: None $(.or(Some($notes.to_string())))?,
195 };
196
197 issue_deprecation_warning(&info);
198 }
199 };
200}
201
202#[macro_export]
204macro_rules! experimental_feature {
205 ($name:expr, $description:expr) => {{
206 use $crate::deprecation::{issue_deprecation_warning, DeprecationInfo, DeprecationLevel};
207
208 let info = DeprecationInfo {
209 name: $name.to_string(),
210 since: "0.1.0-beta.1".to_string(),
211 remove_in: None,
212 level: DeprecationLevel::Experimental,
213 reason: format!("This is an experimental feature: {}", $description),
214 alternative: None,
215 migration_notes: Some("API may change in future versions".to_string()),
216 };
217
218 issue_deprecation_warning(&info);
219 }};
220}
221
222pub struct FeatureRegistry;
224
225impl FeatureRegistry {
226 pub fn deprecated_features() -> Vec<DeprecationInfo> {
228 vec![
229 DeprecationInfo {
231 name: "gpu_accelerated".to_string(),
232 since: "0.1.0-alpha.1".to_string(),
233 remove_in: None,
234 level: DeprecationLevel::Experimental,
235 reason: "GPU acceleration is experimental and may change".to_string(),
236 alternative: None,
237 migration_notes: Some(
238 "Enable with 'gpu' feature flag. API subject to change.".to_string(),
239 ),
240 },
241 DeprecationInfo {
243 name: "neural_enhanced".to_string(),
244 since: "0.1.0-alpha.3".to_string(),
245 remove_in: None,
246 level: DeprecationLevel::Experimental,
247 reason: "Neural enhanced interpolation is experimental".to_string(),
248 alternative: None,
249 migration_notes: Some(
250 "API may change significantly in future versions".to_string(),
251 ),
252 },
253 DeprecationInfo {
255 name: "physics_informed".to_string(),
256 since: "0.1.0-alpha.4".to_string(),
257 remove_in: None,
258 level: DeprecationLevel::Experimental,
259 reason: "Physics-informed methods are experimental".to_string(),
260 alternative: None,
261 migration_notes: Some(
262 "Consider using standard RBF or spline methods for production".to_string(),
263 ),
264 },
265 DeprecationInfo {
267 name: "experimental_kriging_variants".to_string(),
268 since: "0.1.0-alpha.5".to_string(),
269 remove_in: None,
270 level: DeprecationLevel::Experimental,
271 reason: "Some advanced Kriging variants show implementation warnings".to_string(),
272 alternative: Some("enhanced_kriging::make_enhanced_kriging".to_string()),
273 migration_notes: Some(
274 "Use stable Kriging implementations for production workloads".to_string(),
275 ),
276 },
277 ]
278 }
279
280 pub fn features_removed_in(version: &str) -> Vec<DeprecationInfo> {
282 Self::deprecated_features()
283 .into_iter()
284 .filter(|f| f.remove_in.as_ref().map(|v| v == version).unwrap_or(false))
285 .collect()
286 }
287
288 pub fn is_feature_deprecated(featurename: &str) -> bool {
290 Self::deprecated_features()
291 .iter()
292 .any(|f| f.name == featurename)
293 }
294
295 pub fn get_deprecation_info(featurename: &str) -> Option<DeprecationInfo> {
297 Self::deprecated_features()
298 .into_iter()
299 .find(|f| f.name == featurename)
300 }
301}
302
303pub mod convenience {
305 use crate::experimental_feature;
306
307 pub fn warn_gpu_experimental(featurename: &str) {
309 experimental_feature!(
310 featurename,
311 "GPU acceleration support is experimental and may change significantly"
312 );
313 }
314
315 pub fn warn_neural_experimental(featurename: &str) {
317 experimental_feature!(
318 featurename,
319 "Neural network enhanced interpolation is experimental"
320 );
321 }
322
323 pub fn warn_physics_experimental(featurename: &str) {
325 experimental_feature!(
326 featurename,
327 "Physics-informed interpolation methods are experimental"
328 );
329 }
330
331 pub fn warn_matrix_conditioning(condition_number: f64, context: &str) {
333 if condition_number > 1e14 {
334 eprintln!(
335 "NUMERICAL WARNING: Poor matrix conditioning (condition number: {condition_number:.2e}) in {context}. \
336 Consider regularization or data preprocessing."
337 );
338 }
339 }
340
341 pub fn warn_performance_large_dataset(operation: &str, size: usize, threshold: usize) {
343 if size > threshold {
344 eprintln!(
345 "PERFORMANCE WARNING: {operation} with {size} data points may be slow. \
346 Consider using fast variants or GPU acceleration if available."
347 );
348 }
349 }
350}
351
352#[cfg(test)]
353mod tests {
354 use super::*;
355
356 #[test]
357 fn test_deprecation_config() {
358 let config = DeprecationConfig::default();
359 assert!(config.show_warnings);
360 assert!(!config.warnings_as_errors);
361 assert_eq!(config.max_warning_count, 3);
362 }
363
364 #[test]
365 fn test_feature_registry() {
366 let deprecated = FeatureRegistry::deprecated_features();
367 assert!(!deprecated.is_empty());
368
369 let gpu_deprecated = FeatureRegistry::is_feature_deprecated("gpu_accelerated");
370 assert!(gpu_deprecated);
371
372 let standard_feature = FeatureRegistry::is_feature_deprecated("spline");
373 assert!(!standard_feature);
374 }
375
376 #[test]
377 fn test_deprecation_info() {
378 let info = DeprecationInfo {
379 name: "test_function".to_string(),
380 since: "0.1.0".to_string(),
381 remove_in: Some("0.2.0".to_string()),
382 level: DeprecationLevel::Soft,
383 reason: "Test deprecation".to_string(),
384 alternative: Some("new_function".to_string()),
385 migration_notes: Some("Easy migration".to_string()),
386 };
387
388 let message = format_deprecation_warning(&info);
389 assert!(message.contains("test_function"));
390 assert!(message.contains("0.1.0"));
391 assert!(message.contains("0.2.0"));
392 assert!(message.contains("new_function"));
393 }
394}