Crate steckrs

Source
Expand description

§steckrs

A lightweight, trait-based plugin system for Rust applications and libraries.

§What is steckrs?

“steckrs” is a wordplay combining the German word “Stecker” (meaning “plug” or “connector”) and the Rust file extension (.rs). The library provides a flexible, type-safe plugin architecture for Rust applications, allowing developers to:

  • Define extension points in their applications
  • Create plugins that integrate with these extension points
  • Dynamically manage plugins (loading, enabling, disabling, unloading)
  • Register and invoke hooks with proper type safety

§Core Concepts

§Extension Points

Extension points define interfaces where plugins can add functionality. Each extension point:

  • Is defined as a trait that plugins implement
  • Specifies the contract that plugins must fulfill
  • Provides type-safe interaction between the core application and plugins

§Plugins

Plugins are self-contained modules that implement functionality for extension points. Each plugin:

  • Has a unique identifier
  • Can be enabled or disabled at runtime
  • Can register multiple hooks to different extension points
  • Has lifecycle methods (on_load, on_unload)

§Hooks

Hooks are implementations of extension points that plugins register. They:

  • Implement the trait defined by an extension point
  • Are invoked when the application calls that extension point
  • Can be uniquely identified by their plugin ID, extension point, and optional discriminator

§Logs

This library logs certain events with the tracing library.

§Usage Example

Here’s a simple example of how to use steckrs to create a plugin-enabled application:

use steckrs::{extension_point, simple_plugin, PluginManager};

// Define an extension point
extension_point!(
    GreeterExtension: GreeterTrait;
    fn greet(&self, name: &str) -> String;
);

// Create a plugin
simple_plugin!(
    HelloPlugin,
    "hello_plugin",
    "A simple greeting plugin",
    hooks: [(GreeterExtension, EnglishGreeter)]
);

// Implement a hook
struct EnglishGreeter;
impl GreeterTrait for EnglishGreeter {
    fn greet(&self, name: &str) -> String {
        format!("Hello, {}!", name)
    }
}

// Create plugin manager
let mut plugin_manager = PluginManager::new();

// Load and enable the plugin
plugin_manager.load_plugin(Box::new(HelloPlugin::new())).unwrap();
plugin_manager.enable_plugin(HelloPlugin::ID).unwrap();

// Get all enabled hooks (plugins could be disabled)
let hooks = plugin_manager.get_enabled_hooks_by_ep::<GreeterExtension>();

// execute all hooks relevant for this extension point
for (_id, hook) in hooks {
    println!("{}", hook.inner().greet("World"));
}

§Macros

steckrs provides several convenience macros to reduce boilerplate:

Note that register_hook! is not needed if you generate your plugin with simple_plugin!.

§Advanced Usage

For more complex scenarios, you can implement the Plugin trait directly, allowing for more customized plugin behavior and state management.

Modules§

error
Error Types
hook
Hook System
macros
Macros

Macros§

extension_point
Defines a new ExtensionPoint and its associated trait.
register_hook
Registers a Hook with a HookRegistry.
simple_plugin
Creates a simple Plugin with a specified set of hooks.

Structs§

PluginIDOwned
An owned version of PluginID that can be owned and has optional serialization support with serde.
PluginManager
Manages plugin loading, execution, and lifecycle.

Traits§

Plugin
Plugin trait that must be implemented by all plugins.

Type Aliases§

PluginID
Plugin identifier type.