Skip to main content

memscope_rs/facade/
compat.rs

1//! Compatibility layer for legacy API
2//!
3//! This module provides compatibility functions to bridge the old API
4//! with the new facade-based API, ensuring smooth migration for
5//! existing code.
6
7use crate::facade::MemScope;
8use crate::metadata::registry::VariableInfo;
9use std::sync::{Arc, OnceLock};
10
11/// Global MemScope instance for compatibility
12static GLOBAL_MEMSCOPE: OnceLock<Arc<MemScope>> = OnceLock::new();
13
14/// Get or create the global MemScope instance
15///
16/// This function provides compatibility with the old global tracker pattern.
17/// New code should use `MemScope::new()` directly.
18pub fn get_global_memscope() -> Arc<MemScope> {
19    GLOBAL_MEMSCOPE
20        .get_or_init(|| Arc::new(MemScope::new()))
21        .clone()
22}
23
24/// Compatibility wrapper for variable registration
25///
26/// This function is used to register variable metadata with the
27/// global MemScope instance.
28///
29/// # Arguments
30/// * `address` - The memory address of the variable
31/// * `var_name` - The name of the variable
32/// * `type_name` - The type name of the variable
33/// * `size` - The size of the variable in bytes
34pub fn register_variable(address: usize, var_name: String, type_name: String, size: usize) {
35    let memscope = get_global_memscope();
36    memscope
37        .metadata
38        .variable_registry
39        .register_variable(address, var_name, type_name, size);
40}
41
42/// Get variable information by address
43///
44/// # Arguments
45/// * `address` - The memory address of the variable
46///
47/// # Returns
48/// The variable information if found, None otherwise
49pub fn get_variable_info(address: usize) -> Option<VariableInfo> {
50    let memscope = get_global_memscope();
51    memscope
52        .metadata
53        .variable_registry
54        .get_variable_info(address)
55}
56
57/// Get a summary of current memory usage
58///
59/// This function provides compatibility with the old API.
60pub fn get_memory_summary() -> crate::query::SummaryQueryResult {
61    let memscope = get_global_memscope();
62    match memscope.summary() {
63        crate::query::QueryResult::Summary(summary) => summary,
64        _ => crate::query::SummaryQueryResult {
65            total_allocations: 0,
66            total_deallocations: 0,
67            active_allocations: 0,
68            total_allocated: 0,
69            total_deallocated: 0,
70            current_memory: 0,
71            peak_memory: 0,
72            thread_count: 0,
73        },
74    }
75}
76
77/// Get top allocations by size
78///
79/// # Arguments
80/// * `limit` - Maximum number of allocations to return
81pub fn get_top_allocations(limit: usize) -> Vec<crate::snapshot::ActiveAllocation> {
82    let memscope = get_global_memscope();
83    match memscope.top_allocations(limit) {
84        crate::query::QueryResult::Allocations(result) => result.allocations,
85        _ => Vec::new(),
86    }
87}
88
89/// Render current snapshot to JSON
90///
91/// # Arguments
92/// * `verbose` - Whether to include verbose output
93///
94/// # Returns
95/// JSON string of the current memory snapshot
96pub fn export_json(verbose: bool) -> Result<String, String> {
97    let memscope = get_global_memscope();
98    let result = memscope.render_json(verbose)?;
99    String::from_utf8(result.data).map_err(|e| e.to_string())
100}
101
102/// Clear all events and reset state
103pub fn clear_all() {
104    let memscope = get_global_memscope();
105    memscope.clear();
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn test_global_memscope_creation() {
114        let memscope = get_global_memscope();
115        assert_eq!(memscope.event_count(), 0);
116    }
117
118    #[test]
119    fn test_register_variable() {
120        let address = 0x1000;
121        register_variable(address, "test_var".to_string(), "i32".to_string(), 4);
122
123        let info = get_variable_info(address);
124        assert!(info.is_some());
125        let info = info.unwrap();
126        assert_eq!(info.var_name, "test_var");
127        assert_eq!(info.type_name, "i32");
128        assert_eq!(info.size, 4);
129    }
130
131    #[test]
132    fn test_get_memory_summary() {
133        let summary = get_memory_summary();
134        assert_eq!(summary.total_allocations, 0);
135    }
136
137    #[test]
138    fn test_get_top_allocations() {
139        let allocations = get_top_allocations(10);
140        assert!(allocations.is_empty());
141    }
142
143    #[test]
144    fn test_clear_all() {
145        let memscope = get_global_memscope();
146        memscope.clear();
147        assert_eq!(memscope.event_count(), 0);
148    }
149}