Custom Rust Extensions
An extern declaration gives a Rust implementation a Magscript signature.
Use magnet new --rust gain to scaffold the package, then add it as a dependency.
Model header
Section titled “Model header”The header gain/src/gain.mag declares fields and ports:
model Gain { k: f64,}
params Gain(k: f64 = 1.0) { Self { k }}
extern step Gain(u: f64) -> (y: f64);A consumer:
- imports it with
use gain::gain::Gain; - constructs it with
Gain(2.0)in itsparamsbody - steps the instance with
self.gain(u)
Rust contract
Section titled “Rust contract”The dependency directory must contain the implementing Cargo.toml. The DSL
package name identifies the Rust crate; the .mag module path identifies the
Rust module. That module exports Gain and GainParameters.
| Declaration | Rust requirement |
|---|---|
model Gain { k: f64 } |
GainParameters with public field k: f64 |
extern step Gain(...) -> (...) |
Gain implements magnetite::Model |
| Parameters | Model::Parameters = GainParameters |
| Ports | Model::Inputs and Model::Outputs match the declared types and order |
| Initialization | fn init(params: &Self::Parameters) -> Self |
| One tick | fn step(&mut self, ctx: &Ctx, params: &Self::Parameters, inputs: Self::Inputs) -> Self::Outputs |
Zero ports map to (), one port to its type, and multiple ports to a tuple.
The crate must support no_std and use the same magnetite runtime as the
generated crate.
An external model’s explicit constructor must pass each argument directly to
the same-named field, as above. It may supply defaults, but cannot derive fields
through calculations or local bindings. Without params, fields are constructor
arguments under the implicit constructor rules.
Functions and constraints
Section titled “Functions and constraints”External pure functions use a signature followed by a semicolon:
extern fn response(x: f64) -> f64;The Rust module must export the corresponding function. Calls follow the pure function rules.
- External declarations belong in dependency packages. Checking a standalone Rust block package treats it as a dependency of a synthetic host.
- External models cannot be
inline; feedback around them needs an explicit delay. @probecan observe external inputs and outputs, but not Rust internals.- Generic external models require a Rust implementation for each used type instantiation.
magnet checkvalidates the DSL interface.magnet buildcompiles against Rust and reports implementation mismatches through Cargo.