use quantum_pulse::{profile, profile_async, scoped_timer, Category, Operation, ProfileCollector};
use std::thread;
use std::time::Duration;
use tokio::time::sleep;
#[derive(Debug)]
enum AppOperation {
Fibonacci,
SumNumbers,
Iteration,
ManualOperation,
ConditionalOperation,
ExpensiveOperation,
ScopedOperation,
}
#[derive(Debug)]
enum BasicOperation {
Test,
AsyncTest,
FileRead,
AsyncOperation,
}
impl Operation for BasicOperation {
fn to_str(&self) -> String {
match self {
BasicOperation::Test => "test_operation".to_string(),
BasicOperation::AsyncTest => "async_test".to_string(),
BasicOperation::FileRead => "file_read".to_string(),
BasicOperation::AsyncOperation => "async_operation".to_string(),
}
}
}
#[derive(Debug)]
struct ComputeCategory;
impl Category for ComputeCategory {
fn get_name(&self) -> &str {
"Compute"
}
fn get_description(&self) -> &str {
"CPU-intensive computational operations"
}
fn color_hint(&self) -> Option<&str> {
Some("#e74c3c")
}
fn priority(&self) -> i32 {
1
}
}
#[derive(Debug)]
struct IOCategory;
impl Category for IOCategory {
fn get_name(&self) -> &str {
"IO"
}
fn get_description(&self) -> &str {
"Input/Output operations"
}
fn color_hint(&self) -> Option<&str> {
Some("#3498db")
}
fn priority(&self) -> i32 {
2
}
}
impl Operation for AppOperation {
fn get_category(&self) -> &dyn Category {
match self {
AppOperation::Fibonacci
| AppOperation::SumNumbers
| AppOperation::ExpensiveOperation => &ComputeCategory,
AppOperation::ScopedOperation => &IOCategory,
_ => &quantum_pulse::NoCategory,
}
}
fn to_str(&self) -> String {
match self {
AppOperation::Fibonacci => "fibonacci_calc".to_string(),
AppOperation::SumNumbers => "sum_numbers".to_string(),
AppOperation::Iteration => "iteration".to_string(),
AppOperation::ManualOperation => "manual_op".to_string(),
AppOperation::ConditionalOperation => "conditional_op".to_string(),
AppOperation::ExpensiveOperation => "expensive_op".to_string(),
AppOperation::ScopedOperation => "scoped_op".to_string(),
}
}
}
#[tokio::main]
async fn main() {
println!("=== Basic Enum-Based Profiling Example ===\n");
println!("1. Simple function profiling with enums:");
let result = profile!(AppOperation::Fibonacci, { fibonacci(30) });
println!(" Fibonacci(30) = {}", result);
println!("\n2. Using BasicOperation for quick profiling:");
let data = profile!(BasicOperation::FileRead, {
thread::sleep(Duration::from_millis(10));
"file_content"
});
println!(" File data: {}", data);
println!("\n3. Profiling multiple operations with enums:");
for i in 0..3 {
profile!(AppOperation::Iteration, {
thread::sleep(Duration::from_millis(5));
println!(" Completed iteration {}", i);
});
}
println!("\n4. Async operations:");
let async_result = profile_async!(BasicOperation::AsyncOperation, async {
sleep(Duration::from_millis(20)).await;
"async_result"
})
.await;
println!(" Async result: {}", async_result);
println!("\n5. Conditional profiling:");
let enable_profiling = true;
if enable_profiling {
let result = profile!(AppOperation::ConditionalOperation, {
expensive_operation()
});
println!(" Operation result: {}", result);
}
println!("\n6. Scoped timing:");
{
scoped_timer!(AppOperation::ScopedOperation);
println!(" Doing work in a scoped block...");
thread::sleep(Duration::from_millis(10));
println!(" Scoped block complete");
}
println!("\n7. Sum numbers with compute category:");
let sum = profile!(AppOperation::SumNumbers, {
let mut total = 0u64;
for i in 1..=100_000 {
total += i;
}
total
});
println!(" Sum of 1 to 100,000 = {}", sum);
if false {
profile!(AppOperation::ManualOperation, { 42 });
profile!(AppOperation::ExpensiveOperation, { 42 });
let _test_result = profile_async!(BasicOperation::Test, async { 42 }).await;
let _async_test_result = profile_async!(BasicOperation::AsyncTest, async { 42 }).await;
}
println!("\n{}", "=".repeat(70));
println!("PROFILING REPORT");
println!("{}\n", "=".repeat(70));
ProfileCollector::report_stats();
let summary = ProfileCollector::get_summary();
println!("\nSummary:");
println!("- Total operations: {}", summary.total_operations);
println!("- Unique operations: {}", summary.unique_operations);
println!("- Total time: {}μs", summary.total_time_micros);
println!("\n{}", "=".repeat(70));
println!("DETAILED OPERATION STATISTICS");
println!("{}\n", "=".repeat(70));
let all_stats = ProfileCollector::get_all_stats();
for (operation_name, stats) in all_stats {
println!("📊 {}:", operation_name);
println!(" Calls: {}", stats.count);
println!(" Mean: {:?}", stats.mean());
println!(" Total: {:?}", stats.total);
println!();
}
}
fn fibonacci(n: u32) -> u64 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
fn expensive_operation() -> i32 {
thread::sleep(Duration::from_millis(25));
42
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_app_operation_categories() {
let fib_op = AppOperation::Fibonacci;
assert_eq!(fib_op.get_category().get_name(), "Compute");
assert_eq!(fib_op.to_str(), "fibonacci_calc");
let scoped_op = AppOperation::ScopedOperation;
assert_eq!(scoped_op.get_category().get_name(), "IO");
assert_eq!(scoped_op.to_str(), "scoped_op");
let iter_op = AppOperation::Iteration;
assert_eq!(iter_op.get_category().get_name(), "NoCategory");
assert_eq!(iter_op.to_str(), "iteration");
}
#[test]
fn test_profiling_with_operations() {
ProfileCollector::clear_all();
let op = AppOperation::Fibonacci;
profile!(op, { fibonacci(5) });
assert!(ProfileCollector::has_data());
let stats = ProfileCollector::get_stats("Compute::fibonacci_calc");
assert!(stats.is_some());
assert_eq!(stats.unwrap().count, 1);
}
#[tokio::test]
async fn test_async_profiling() {
ProfileCollector::clear_all();
let result = profile_async!(BasicOperation::AsyncTest, async {
sleep(Duration::from_millis(1)).await;
42
})
.await;
assert_eq!(result, 42);
assert!(ProfileCollector::has_data());
}
}