Skip to content

colliery-io/fidius

Repository files navigation

fidius

fidius

A Rust plugin framework for trait-to-dylib plugin systems

fidius lets you define a Rust trait, annotate it with a macro, and get a compiled dynamic library with a stable C ABI. Host applications load, validate, and call plugins through a type-safe proxy — no handwritten FFI.

Features

  • Trait-driven — define a plugin interface as a Rust trait; the macro generates the ABI shim.
  • Stable C ABI — plugins compile to .dylib/.so/.dll with versioned, hash-checked entry points.
  • Type-safe host loadingfidius-host loads plugins behind a typed proxy that mirrors your trait.
  • Optional methods & interface evolution — add methods without breaking existing plugins.
  • Signing & verification — Ed25519 signatures over plugin artifacts.
  • Python plugins — write plugins in Python that satisfy a Rust trait via fidius-python.
  • Sandboxed WASM plugins — compile a plugin to a WebAssembly component that runs in a deny-all wasmtime sandbox with a capability allow-list; polyglot (Rust and other languages implement the same interface). Outbound HTTP is host-brokered and policy-gated (wasi:http + a required egress hook).
  • Streaming, all three directionsfidius::Stream<T> works in return position (server-streaming — the plugin produces), argument position (client-streaming — the host produces), or both (bidirectional — a plugin-owned transform). Pull-based, backpressured, drop-to-cancel, with bounded memory for unbounded inputs — on all three backends (Rust/Python/WASM), and server-streaming proven across Rust, JS, Python, and C guests.
  • Configured instances — bind config once and call many (#[plugin_impl(Trait, config = C)] + configure): config crosses the boundary once, config-bound setup runs once, and N differently-configured instances coexist — on all three backends (cdylib/WASM/Python).
  • CLI tooling — scaffold interfaces and plugins, sign, inspect, and package.

Workspace Layout

Crate Purpose
fidius Top-level facade re-exporting the public API
fidius-core Descriptors, wire format, hashing, registry, metadata
fidius-macro Proc macros (#[fidius::interface], #[fidius::plugin]) and IR
fidius-host Loading, calling, signing, arch detection, arena pool
fidius-cli fidius command-line tool
fidius-test Test helpers (dylib fixtures, signing fixtures)
fidius-python Python plugin support
fidius-guest wasm-buildable guest types for plugins compiled to WASM components

Installation

cargo install fidius-cli

Quick Example

A fidius plugin system is three crates: an interface (the trait), a plugin (a cdylib that implements it), and a host (loads and calls it). The CLI scaffolds the first two:

fidius init-interface my-api    --trait ImageFilter
fidius init-plugin    my-plugin --interface my-api --trait ImageFilter

You then fill in two small pieces of code. In the interface crate, annotate the trait — the macro generates the vtable, ABI hash, and the host-side typed proxy:

use serde::{Deserialize, Serialize};

#[fidius::plugin_interface(version = 1, buffer = PluginAllocated)]
pub trait ImageFilter: Send + Sync {
    fn apply(&self, input: ApplyInput) -> ApplyOutput;
}

#[derive(Serialize, Deserialize)]
pub struct ApplyInput  { pub pixels: Vec<u8> }
#[derive(Serialize, Deserialize)]
pub struct ApplyOutput { pub pixels: Vec<u8> }

In the plugin crate, annotate your impl and emit the registry — that's all the FFI you write:

use my_api::{plugin_impl, ImageFilter, ApplyInput, ApplyOutput};

pub struct Invert;

#[plugin_impl(ImageFilter)]
impl ImageFilter for Invert {
    fn apply(&self, input: ApplyInput) -> ApplyOutput {
        ApplyOutput { pixels: input.pixels.into_iter().map(|p| 255 - p).collect() }
    }
}

fidius::fidius_plugin_registry!();

Then build, optionally sign, and inspect:

cd my-plugin && cargo build

fidius keygen --out mykey
fidius sign --key mykey.secret target/debug/libmy_plugin.dylib
fidius inspect target/debug/libmy_plugin.dylib

The host loads the resulting dylib through fidius-host and calls apply() through a generated ImageFilterClient proxy. See Your First Plugin for the full walkthrough including the host crate.

Development

This project uses angreal as its task runner. Common tasks:

angreal tree            # list all tasks
angreal build           # build the workspace
angreal test            # run the test suite
angreal python-test     # run the Python SDK tests
angreal check           # cargo check + clippy
angreal lint            # formatting and lint checks
angreal license-header  # add/check license headers

Documentation

Full documentation lives in docs/ and covers tutorials, how-to guides, reference, and architecture explanation. Build it locally with mkdocs serve.

License

Apache-2.0. See LICENSE.

About

Fidius — a Rust plugin framework for trait-to-dylib plugin systems

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages