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