use crate::meta_plugin::{MetaPlugin, MetaPluginType}; #[derive(Debug, Clone, Default)] /// Meta plugin for capturing current user and group information. /// /// This plugin collects user ID, group ID, username, and group name for the process /// running the keep application, providing context about the creator of items. pub struct UserMetaPlugin { base: crate::meta_plugin::BaseMetaPlugin, } impl UserMetaPlugin { /// Creates a new `UserMetaPlugin` instance. /// /// # Arguments /// /// * `options` - Optional configuration options for the plugin. /// * `outputs` - Optional output mappings for metadata. /// /// # Returns /// /// A new instance of `UserMetaPlugin`. pub fn new( options: Option>, outputs: Option>, ) -> UserMetaPlugin { let mut base = crate::meta_plugin::BaseMetaPlugin::new(); // Initialize with helper function base.initialize_plugin( &["user_uid", "user_gid", "user_name", "user_group"], options, outputs, ); UserMetaPlugin { base, } } /// Gets the current username. /// /// # Returns /// /// An `Option` with the username, or `None` if unavailable. fn get_current_username() -> Option { uzers::get_user_by_uid(uzers::get_current_uid()) .map(|user| user.name().to_string_lossy().to_string()) } /// Gets the current group name. /// /// # Returns /// /// An `Option` with the group name, or `None` if unavailable. fn get_current_groupname() -> Option { uzers::get_group_by_gid(uzers::get_current_gid()) .map(|group| group.name().to_string_lossy().to_string()) } } impl MetaPlugin for UserMetaPlugin { /// Initializes the plugin, capturing user information. /// /// # Returns /// /// A `MetaPluginResponse` with user metadata and `is_finalized` set to `true`. fn initialize(&mut self) -> crate::meta_plugin::MetaPluginResponse { let mut metadata = Vec::new(); // Get user info let uid = uzers::get_current_uid().to_string(); let gid = uzers::get_current_gid().to_string(); let username = Self::get_current_username().unwrap_or_else(|| "unknown".to_string()); let groupname = Self::get_current_groupname().unwrap_or_else(|| "unknown".to_string()); // Process each output let values = [ ("user_uid", uid), ("user_gid", gid), ("user_name", username), ("user_group", groupname), ]; for (name, value) in values { if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( name, serde_yaml::Value::String(value), self.base.outputs() ) { metadata.push(meta_data); } } crate::meta_plugin::MetaPluginResponse { metadata, is_finalized: true, } } /// Returns the type of this meta plugin. /// /// # Returns /// /// `MetaPluginType::User`. fn meta_type(&self) -> MetaPluginType { MetaPluginType::User } /// Returns a reference to the outputs mapping. /// /// # Returns /// /// A reference to the `HashMap` of outputs. fn outputs(&self) -> &std::collections::HashMap { self.base.outputs() } /// Returns a mutable reference to the outputs mapping. /// /// # Returns /// /// A mutable reference to the `HashMap` of outputs. fn outputs_mut(&mut self) -> &mut std::collections::HashMap { self.base.outputs_mut() } /// Returns the default output names. /// /// # Returns /// /// A vector of default output names. fn default_outputs(&self) -> Vec { vec!["user_uid".to_string(), "user_gid".to_string(), "user_name".to_string(), "user_group".to_string()] } /// Returns a reference to the options mapping. /// /// # Returns /// /// A reference to the `HashMap` of options. fn options(&self) -> &std::collections::HashMap { self.base.options() } /// Returns a mutable reference to the options mapping. /// /// # Returns /// /// A mutable reference to the `HashMap` of options. fn options_mut(&mut self) -> &mut std::collections::HashMap { self.base.options_mut() } } use crate::meta_plugin::register_meta_plugin; // Register the plugin at module initialization time #[ctor::ctor] fn register_user_plugin() { register_meta_plugin(MetaPluginType::User, |options, outputs| { Box::new(UserMetaPlugin::new(options, outputs)) }); }