#[cfg(target_os = "linux")]
use quanta::Instant;
#[cfg(not(target_os = "linux"))]
use std::time::Instant;
use prettytable::{Cell, Row, Table};
use crate::futures::{get_futures_json, init_futures_state, FuturesJson};
use crate::Format;
#[must_use = "builder is discarded without creating a guard"]
pub struct FuturesGuardBuilder {
format: Format,
}
impl FuturesGuardBuilder {
pub fn new() -> Self {
Self {
format: Format::default(),
}
}
pub fn format(mut self, format: Format) -> Self {
self.format = format;
self
}
pub fn build(self) -> FuturesGuard {
init_futures_state();
FuturesGuard {
start_time: Instant::now(),
format: self.format,
}
}
}
impl Default for FuturesGuardBuilder {
fn default() -> Self {
Self::new()
}
}
#[must_use = "guard is dropped immediately without printing statistics"]
pub struct FuturesGuard {
start_time: Instant,
format: Format,
}
impl FuturesGuard {
pub fn new() -> Self {
init_futures_state();
Self {
start_time: Instant::now(),
format: Format::default(),
}
}
pub fn format(mut self, format: Format) -> Self {
self.format = format;
self
}
}
impl Default for FuturesGuard {
fn default() -> Self {
Self::new()
}
}
impl Drop for FuturesGuard {
fn drop(&mut self) {
let elapsed = self.start_time.elapsed();
let futures_json = get_futures_json();
if futures_json.futures.is_empty() {
println!("\nNo instrumented futures found.");
return;
}
match self.format {
Format::Table => {
println!(
"\n=== Future Statistics (runtime: {:.2}s) ===",
elapsed.as_secs_f64()
);
let mut table = Table::new();
table.add_row(Row::new(vec![
Cell::new("Future"),
Cell::new("Calls"),
Cell::new("Polls"),
]));
for future_stats in &futures_json.futures {
table.add_row(Row::new(vec![
Cell::new(&future_stats.label),
Cell::new(&future_stats.call_count.to_string()),
Cell::new(&future_stats.total_polls.to_string()),
]));
}
println!("\nFutures:");
table.printstd();
}
Format::Json => {
let json_output = FuturesJson {
current_elapsed_ns: elapsed.as_nanos() as u64,
futures: futures_json.futures,
};
match serde_json::to_string(&json_output) {
Ok(json) => println!("{}", json),
Err(e) => eprintln!("Failed to serialize statistics to JSON: {}", e),
}
}
Format::JsonPretty => {
let json_output = FuturesJson {
current_elapsed_ns: elapsed.as_nanos() as u64,
futures: futures_json.futures,
};
match serde_json::to_string_pretty(&json_output) {
Ok(json) => println!("{}", json),
Err(e) => eprintln!("Failed to serialize statistics to pretty JSON: {}", e),
}
}
}
}
}