Native Plugins & Advanced FFI
In addition to external crates, you can write custom native Rust code inside your project and call it directly from Flame with zero runtime overhead.
Building a Custom Plugin: Axum + Tokio Web Server
Section titled “Building a Custom Plugin: Axum + Tokio Web Server”-
Initialize Rust Workspace
Section titled “Initialize Rust Workspace”Create a
nativefolder containingnative/Cargo.tomlandnative/src/lib.rs:native/Cargo.toml [package]name = "server"version = "0.1.0"edition = "2021"[dependencies]axum = "0.7"tokio = { version = "1.0", features = ["full"] }flame-macro = "0.1.0" -
Implement Structs & Methods (
Section titled “Implement Structs & Methods (lib.rs)”lib.rs)native/src/lib.rs use axum::{routing::{get, post},Router,};use flame_macro::flame;use std::mem;use std::net::SocketAddr;pub struct FlameServer {router: Router,}#[derive(Debug, Clone)]pub struct Request {pub body: String,}#[derive(Debug, Clone)]pub struct Response {pub body: String,}// Module-level function/// Initialize a new FlameServer instance.pub fn init() -> FlameServer {FlameServer {router: Router::new(),}}impl FlameServer {pub fn get<H, T>(&mut self, path: &'static str, handler: H)whereH: axum::handler::Handler<T, ()> + Clone + Send + Sync + 'static,T: 'static,{let router = mem::take(&mut self.router);self.router = router.route(path, get(handler));}pub fn post<H, T>(&mut self, path: &'static str, handler: H)whereH: axum::handler::Handler<T, ()> + Clone + Send + Sync + 'static,T: 'static,{let router = mem::take(&mut self.router);self.router = router.route(path, post(handler));}pub fn router(&mut self) -> Router {mem::take(&mut self.router)}#[flame(daemon)]pub async fn listen(self, port: u16) -> std::io::Result<()> {let addr = SocketAddr::from(([127, 0, 0, 1], port));let listener = tokio::net::TcpListener::bind(addr).await?;axum::serve(listener, self.router).await.map_err(std::io::Error::other)}} -
Register in
Section titled “Register in flame.toml”flame.toml[plugins]server = "./native" -
Call from Flame Source
Section titled “Call from Flame Source”import native.flamerlet app = flamer.init()fn main() -> String {"hello"}app.get("/", main)print("Server started!")app.listen(3000)
