diff --git a/src/meta_plugin/digest.rs b/src/meta_plugin/digest.rs index 0ef1caa..e54ab65 100644 --- a/src/meta_plugin/digest.rs +++ b/src/meta_plugin/digest.rs @@ -2,6 +2,7 @@ use anyhow::Result; use sha2::{Digest, Sha256}; use std::io; use std::io::Write; +use std::time::Instant; use crate::meta_plugin::MetaPlugin; @@ -39,7 +40,6 @@ impl MetaPlugin for DigestSha256MetaPlugin { fn meta_name(&mut self) -> String { self.meta_name.clone() } - } // Dummy writer that implements Write but doesn't do anything @@ -55,3 +55,93 @@ impl Write for DummyWriter { Ok(()) } } + +#[derive(Debug, Clone, Default)] +pub struct ReadTimeMetaPlugin { + start_time: Option, + meta_name: String, +} + +impl ReadTimeMetaPlugin { + pub fn new() -> ReadTimeMetaPlugin { + ReadTimeMetaPlugin { + start_time: None, + meta_name: "read_time".to_string(), + } + } +} + +impl MetaPlugin for ReadTimeMetaPlugin { + fn create(&self) -> Result> { + // For meta plugins, we don't actually create a writer since we're buffering data internally + Ok(Box::new(DummyWriter)) + } + + fn finalize(&mut self) -> io::Result { + if let Some(start_time) = self.start_time { + let duration = start_time.elapsed(); + Ok(format!("{:.6}", duration.as_secs_f64())) + } else { + Ok("0.000000".to_string()) + } + } + + fn update(&mut self, _data: &[u8]) { + if self.start_time.is_none() { + self.start_time = Some(Instant::now()); + } + } + + fn meta_name(&mut self) -> String { + self.meta_name.clone() + } +} + +#[derive(Debug, Clone, Default)] +pub struct ReadRateMetaPlugin { + start_time: Option, + bytes_read: u64, + meta_name: String, +} + +impl ReadRateMetaPlugin { + pub fn new() -> ReadRateMetaPlugin { + ReadRateMetaPlugin { + start_time: None, + bytes_read: 0, + meta_name: "read_rate".to_string(), + } + } +} + +impl MetaPlugin for ReadRateMetaPlugin { + fn create(&self) -> Result> { + // For meta plugins, we don't actually create a writer since we're buffering data internally + Ok(Box::new(DummyWriter)) + } + + fn finalize(&mut self) -> io::Result { + if let Some(start_time) = self.start_time { + let duration = start_time.elapsed(); + if duration.as_secs_f64() > 0.0 { + let rate = self.bytes_read as f64 / duration.as_secs_f64(); + Ok(format!("{:.0}", rate)) + } else { + Ok("0".to_string()) + } + } else { + Ok("0".to_string()) + } + } + + fn update(&mut self, data: &[u8]) { + if self.start_time.is_none() { + self.start_time = Some(Instant::now()); + } + self.bytes_read += data.len() as u64; + } + + fn meta_name(&mut self) -> String { + self.meta_name.clone() + } +}