How to write a plugin
This guide shows you how to create a plugin that contributes a rule to a RuleAcceptor — the type-safe extension point every operation uses.
Goal
A plugin that declares a greeting.punctuation option via the OptionsPlugin acceptor.
Steps
1. Depend on the platform
toml
[dependencies]
handl-platform = { git = "https://github.com/handl-lang/host" }
serde_json = "1"2. Implement Plugin
rust
use handl_platform::{
CapabilityId, CapabilityMetadata, CapabilityRequest, CapabilityResponse,
ContributionContext, OptionSchema, OptionScope, OptionsPlugin,
PlatformError, Plugin, PluginContext,
};
use serde_json::json;
pub struct GreetPlugin {
capabilities: Vec<CapabilityId>,
}
impl Plugin for GreetPlugin {
fn name(&self) -> &str { "greet" }
fn capabilities(&self) -> &[CapabilityId] { &self.capabilities }
fn metadata(&self, _cap: &CapabilityId) -> Option<CapabilityMetadata> { None }
fn contribute(&self, ctx: &mut ContributionContext) -> Result<(), PlatformError> {
ctx.contribute::<OptionsPlugin>(OptionSchema {
id: "greeting.punctuation".to_string(),
scope: OptionScope::Global,
applies_to: Some("greet".to_string()),
default: json!("!"),
possible_values: vec![json!("!"), json!(".")],
description: "How to end the greeting".to_string(),
})?;
Ok(())
}
fn run(
&self,
_request: &CapabilityRequest,
_ctx: &mut PluginContext,
) -> Result<CapabilityResponse, PlatformError> {
Ok(CapabilityResponse(json!("Hello!")))
}
}contribute::<OptionsPlugin> is checked at compile time — the rule must match the acceptor's Rule associated type (OptionSchema here).
3. Register the plugin and the acceptor
rust
host.register_plugin(OptionsPlugin::new());
host.register_plugin(GreetPlugin::new());
host.load()?;Common cases
Swap the RuleAcceptor type parameter for other rule kinds:
contribute::<BasicFormatter>(Box::new(rule))forFormatrules.contribute::<BasicLinter>(Box::new(rule))forLintrules.contribute::<BasicEvaluator>(rule)forEvalrules.ctx.register_plugin(plugin)for library plugins that register more plugins.
If the acceptor is not registered yet, the rule is deferred and applied as soon as it appears — contribution order does not matter.