1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! Plugin System
use log::warn;
use shrs_core::shell::{Context, Runtime, Shell};
use crate::ShellConfig;
#[derive(Debug)]
pub struct PluginMeta {
pub name: String,
pub description: String,
}
/// How should the plugin be handled if it errors during initialization
#[derive(Debug)]
pub enum FailMode {
/// Display a warning but continue with shell initialization
Warn,
/// Abort entire shell initialization process and crash
Abort,
}
impl Default for PluginMeta {
fn default() -> Self {
Self {
name: String::from("unnamed plugin"),
description: String::from("a plugin for shrs"),
}
}
}
/// Implement this trait to build your own plugins
pub trait Plugin {
/// Plugin initialization
///
/// Hook onto the initialization of the shell and add any hooks, functions, state variables
/// that you would like
fn init(&self, shell: &mut ShellConfig) -> anyhow::Result<()>;
/// Plugin post initialization
///
/// Gets called once after the shell has completed initialization process, giving access to
/// shell, context, and runtime state
fn post_init(&self, sh: &Shell, ctx: &mut Context, rt: &mut Runtime) -> anyhow::Result<()> {
Ok(())
}
/// Return metadata related to the plugin
fn meta(&self) -> PluginMeta {
// TODO this is currently an optional method to make migrating all the existing plugins a
// bit easier. Could remove the default implementation in the future
warn!("Using default plugin metadata. Please specify this information for your plugin by implementing Plugin::meta()");
PluginMeta::default()
}
/// Get the fail mode for this plugin
///
/// Provide implementation for this if you want non-default behavior
fn fail_mode(&self) -> FailMode {
// Default to more strict fail mode to let users know faster there's a bug
//
// Should consider more how good of an idea this is
FailMode::Abort
}
}
/// Extension trait to make [ShellConfig] support plugins
pub trait ShellPlugin {
fn with_plugin(&mut self, plugin: impl Plugin);
}