use std::time::Instant;
use prettytable::{Cell, Row, Table};
use crate::{
format_bytes, get_combined_json, get_sorted_channel_stats, get_sorted_stream_stats,
resolve_label, Format,
};
pub struct ChannelsGuardBuilder {
format: Format,
}
impl ChannelsGuardBuilder {
pub fn new() -> Self {
Self {
format: Format::default(),
}
}
pub fn format(mut self, format: Format) -> Self {
self.format = format;
self
}
pub fn build(self) -> ChannelsGuard {
ChannelsGuard {
start_time: Instant::now(),
format: self.format,
}
}
}
impl Default for ChannelsGuardBuilder {
fn default() -> Self {
Self::new()
}
}
pub struct ChannelsGuard {
start_time: Instant,
format: Format,
}
impl ChannelsGuard {
pub fn new() -> Self {
Self {
start_time: Instant::now(),
format: Format::default(),
}
}
pub fn format(mut self, format: Format) -> Self {
self.format = format;
self
}
}
impl Default for ChannelsGuard {
fn default() -> Self {
Self::new()
}
}
impl Drop for ChannelsGuard {
fn drop(&mut self) {
let elapsed = self.start_time.elapsed();
let channels = get_sorted_channel_stats();
let streams = get_sorted_stream_stats();
if channels.is_empty() && streams.is_empty() {
println!("\nNo instrumented channels or streams found.");
return;
}
match self.format {
Format::Table => {
println!(
"\n=== Statistics (runtime: {:.2}s) ===",
elapsed.as_secs_f64()
);
if !channels.is_empty() {
let mut table = Table::new();
table.add_row(Row::new(vec![
Cell::new("Channel"),
Cell::new("Type"),
Cell::new("State"),
Cell::new("Sent"),
Cell::new("Received"),
Cell::new("Queued"),
Cell::new("Mem"),
]));
for channel_stats in channels {
let label = resolve_label(
channel_stats.source,
channel_stats.label.as_deref(),
channel_stats.iter,
);
table.add_row(Row::new(vec![
Cell::new(&label),
Cell::new(&channel_stats.channel_type.to_string()),
Cell::new(channel_stats.state.as_str()),
Cell::new(&channel_stats.sent_count.to_string()),
Cell::new(&channel_stats.received_count.to_string()),
Cell::new(&channel_stats.queued().to_string()),
Cell::new(&format_bytes(channel_stats.queued_bytes())),
]));
}
println!("\nChannels:");
table.printstd();
}
if !streams.is_empty() {
let mut table = Table::new();
table.add_row(Row::new(vec![
Cell::new("Stream"),
Cell::new("State"),
Cell::new("Yielded"),
]));
for stream_stats in streams {
let label = resolve_label(
stream_stats.source,
stream_stats.label.as_deref(),
stream_stats.iter,
);
table.add_row(Row::new(vec![
Cell::new(&label),
Cell::new(stream_stats.state.as_str()),
Cell::new(&stream_stats.items_yielded.to_string()),
]));
}
println!("\nStreams:");
table.printstd();
}
}
Format::Json => {
let combined = get_combined_json();
match serde_json::to_string(&combined) {
Ok(json) => println!("{}", json),
Err(e) => eprintln!("Failed to serialize statistics to JSON: {}", e),
}
}
Format::JsonPretty => {
let combined = get_combined_json();
match serde_json::to_string_pretty(&combined) {
Ok(json) => println!("{}", json),
Err(e) => eprintln!("Failed to serialize statistics to pretty JSON: {}", e),
}
}
}
}
}