Skip to main content

memscope_rs/facade/
macros.rs

1//! Facade Macros - Convenient macros for memory tracking
2//!
3//! This module provides macros that simplify common memory tracking
4/// operations, making the API more ergonomic and reducing boilerplate.
5use std::collections::hash_map::DefaultHasher;
6use std::hash::{Hash, Hasher};
7use std::thread;
8
9/// Helper function to hash thread ID
10#[doc(hidden)]
11pub fn get_heap_ptr_if_trackable<T: crate::Trackable>(value: &T) -> Option<usize> {
12    match value.track_kind() {
13        crate::TrackKind::HeapOwner { ptr, size: _ } => Some(ptr),
14        crate::TrackKind::StackOwner { heap_ptr, .. } => Some(heap_ptr),
15        crate::TrackKind::Container | crate::TrackKind::Value => None,
16    }
17}
18
19/// Helper function to hash thread ID
20#[doc(hidden)]
21pub fn hash_thread_id() -> u64 {
22    let thread_id = thread::current().id();
23    let thread_id_str = format!("{:?}", thread_id);
24    let mut hasher = DefaultHasher::new();
25    thread_id_str.hash(&mut hasher);
26    hasher.finish()
27}
28
29/// Get a memory snapshot and display summary
30///
31/// This macro creates a quick summary of current memory usage,
32/// useful for debugging and monitoring.
33///
34/// # Examples
35///
36/// ```rust
37/// use tracing::{info, debug};
38/// use memscope_rs::memscope_summary;
39///
40/// memscope_summary!();
41/// ```
42#[macro_export]
43macro_rules! memscope_summary {
44    () => {
45        let summary = $crate::facade::compat::get_memory_summary();
46        info!(
47            "Memory Summary: {} allocations, {} active, {} bytes current, {} bytes peak, {} threads",
48            summary.total_allocations,
49            summary.active_allocations,
50            summary.current_memory,
51            summary.peak_memory,
52            summary.thread_count
53        );
54        println!("Memory Summary:");
55        println!("  Total Allocations: {}", summary.total_allocations);
56        println!("  Active Allocations: {}", summary.active_allocations);
57        println!("  Current Memory: {} bytes", summary.current_memory);
58        println!("  Peak Memory: {} bytes", summary.peak_memory);
59        println!("  Thread Count: {}", summary.thread_count);
60    };
61}
62
63/// Get top allocations and display them
64///
65/// This macro shows the largest memory allocations, useful for
66/// identifying memory usage patterns.
67///
68/// # Examples
69///
70/// ```rust
71/// use tracing::{info, debug};
72/// use memscope_rs::show_top_allocations;
73///
74/// show_top_allocations!(10);
75/// ```
76#[macro_export]
77macro_rules! show_top_allocations {
78    ($limit:expr) => {
79        let allocations = $crate::facade::compat::get_top_allocations($limit);
80        info!("Showing top {} allocations by size", $limit);
81        println!("Top {} Allocations by Size:", $limit);
82        for (i, alloc) in allocations.iter().enumerate() {
83            let ptr_str = alloc
84                .ptr
85                .map(|p| format!("{:x}", p))
86                .unwrap_or_else(|| "None".to_string());
87            debug!("Allocation {}: {} bytes at {}", i + 1, alloc.size, ptr_str);
88            println!("  {}. {} bytes at {}", i + 1, alloc.size, ptr_str);
89        }
90    };
91}
92
93/// Export memory data to JSON and print the result
94///
95/// This macro is a convenient way to export memory data
96/// in JSON format for external processing or analysis.
97///
98/// # Examples
99///
100/// ```rust
101/// use memscope_rs::export_memory_json;
102///
103/// export_memory_json!(true);
104/// ```
105#[macro_export]
106macro_rules! export_memory_json {
107    ($verbose:expr) => {
108        match $crate::facade::compat::export_json($verbose) {
109            Ok(json) => {
110                tracing::info!("Memory data exported to JSON:\n{}", json);
111            }
112            Err(e) => {
113                tracing::error!("Failed to export memory data: {}", e);
114            }
115        }
116    };
117}
118
119#[cfg(test)]
120mod tests {
121    #[test]
122    fn test_memscope_summary_macro_compiles() {
123        // This test just ensures the macro compiles correctly
124        // We don't actually run it to avoid printing to stdout during tests
125    }
126}