use std::time::Instant; use crate::meta_plugin::{BaseMetaPlugin, MetaPlugin, MetaPluginType}; #[derive(Debug, Clone, Default)] pub struct ReadTimeMetaPlugin { start_time: Option, is_finalized: bool, base: BaseMetaPlugin, } impl ReadTimeMetaPlugin { pub fn new( _options: Option>, outputs: Option>, ) -> ReadTimeMetaPlugin { let mut base = BaseMetaPlugin::new(); // Set default outputs let default_outputs = &["read_time"]; base.initialize_plugin(default_outputs, &_options, &outputs); ReadTimeMetaPlugin { start_time: None, is_finalized: false, base, } } } impl MetaPlugin for ReadTimeMetaPlugin { fn is_finalized(&self) -> bool { self.is_finalized } fn set_finalized(&mut self, finalized: bool) { self.is_finalized = finalized; } fn set_save_meta(&mut self, save_meta: crate::meta_plugin::SaveMetaFn) { self.base.set_save_meta(save_meta); } fn save_meta(&self, name: &str, value: &str) { self.base.save_meta(name, value); } fn finalize(&mut self) -> crate::meta_plugin::MetaPluginResponse { // If already finalized, don't process again if self.is_finalized { return crate::meta_plugin::MetaPluginResponse { metadata: Vec::new(), is_finalized: true, }; } let mut metadata = Vec::new(); if let Some(start_time) = self.start_time { let duration = start_time.elapsed(); let duration_str = format!("{:.3} seconds", duration.as_secs_f64()); // Use process_metadata_outputs to handle output mapping if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "read_time", serde_yaml::Value::String(duration_str), self.base.outputs(), ) { metadata.push(meta_data); } } // Mark as finalized self.is_finalized = true; crate::meta_plugin::MetaPluginResponse { metadata, is_finalized: true, } } fn update(&mut self, _data: &[u8]) -> crate::meta_plugin::MetaPluginResponse { // If already finalized, don't process more data if self.is_finalized { return crate::meta_plugin::MetaPluginResponse { metadata: Vec::new(), is_finalized: true, }; } if self.start_time.is_none() { self.start_time = Some(Instant::now()); } crate::meta_plugin::MetaPluginResponse { metadata: Vec::new(), is_finalized: false, } } fn meta_type(&self) -> MetaPluginType { MetaPluginType::ReadTime } fn outputs(&self) -> &std::collections::HashMap { self.base.outputs() } fn outputs_mut( &mut self, ) -> anyhow::Result<&mut std::collections::HashMap> { Ok(self.base.outputs_mut()) } fn default_outputs(&self) -> Vec { vec!["read_time".to_string()] } fn options(&self) -> &std::collections::HashMap { self.base.options() } fn options_mut( &mut self, ) -> anyhow::Result<&mut std::collections::HashMap> { Ok(self.base.options_mut()) } } use crate::meta_plugin::register_meta_plugin; // Register the plugin at module initialization time #[ctor::ctor] fn register_read_time_plugin() { register_meta_plugin(MetaPluginType::ReadTime, |options, outputs| { Box::new(ReadTimeMetaPlugin::new(options, outputs)) }) .expect("Failed to register ReadTimeMetaPlugin"); }