RustCall.jl is a Julia package for calling Rust code directly. It covers the common paths from this repository: inline Rust via rust"""...""", explicit FFI calls with @rust, lightweight inline expressions with @irust, #[julia]-based wrapper generation, and external crate loading with @rust_crate.
It is inspired by Cxx.jl, but targets Rust.
Requirements:
- Julia 1.12 or later
- Rust toolchain (
rustcandcargo) available inPATH
using Pkg
Pkg.add("RustCall")RustCall.jl is registered in Julia's General registry. Pkg.add("RustCall") installs the package and builds the helper library used by ownership-related features such as RustBox, RustRc, RustArc, RustVec, and RustSlice.
If the helper library needs to be rebuilt, run:
using Pkg
Pkg.build("RustCall")The simplest path is to annotate Rust functions with #[julia] and call the generated Julia wrapper directly.
using RustCall
rust"""
#[julia]
fn add(a: i32, b: i32) -> i32 {
a + b
}
"""
add(10, 20) # 30If you want explicit C-ABI style calls, use @rust.
using RustCall
rust"""
#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
a * b
}
"""
@rust multiply(Int32(6), Int32(7))::Int32 # 42For small expressions inside Julia functions, @irust captures Julia variables with $var.
using RustCall
function affine(a, x, b)
@irust("\$a * \$x + \$b")
end
affine(Int32(2), Int32(10), Int32(3)) # 23The snippet is the body of the generated function — a trailing expression is
its value, return works, and statements and multi-line snippets are fine —
and its return type is taken from rustc rather than guessed from the text.
$$ is a literal $ (for a macro_rules! metavariable), and a Rust panic
inside a snippet is a catchable RustCall.RustPanicError.
@irust is for exploration at the REPL or in a notebook. It is deliberately
small:
- scalars only — arguments and results must be
Int8…Int64,UInt8…UInt64,Float32,Float64orBool; noString, arrays, structs or 128-bit integers; $namesubstitution is textual, so it happens inside Rust string literals too, and$obj.fieldinterpolatesobjonly;- not type-stable — the return type is decided at run time from the snippet;
- compiler invocations per new snippet (on first use: the type probe, a confirmation of its answer, and the build), memoized for the rest of the session.
Anything beyond a small scalar expression belongs in rust"""...""" with
@rust: it takes its types from the Rust side, generates the wrapper once, is
type-stable, and handles String, Result/Option and #[julia] structs.
The same computation both ways:
# @irust — a one-off scalar expression
hypot_irust(a, b) = @irust("(\$a * \$a + \$b * \$b).sqrt()")
hypot_irust(3.0, 4.0) # 5.0
# rust""" — what a package should ship
rust"""
#[julia]
fn hypot_rs(a: f64, b: f64) -> f64 {
(a * a + b * b).sqrt()
}
"""
hypot_rs(3.0, 4.0) # 5.0rust"""..."""/@rust_str: compile Rust code, cache the build artifact, and make it available in the current Julia module#[julia]: generate Julia-callable wrappers for Rust functions and structs@rust: call exported functions through a C-compatible ABI@irust: compile a small Rust expression with Julia variable capture@rust_crate: build and load an external crate annotated with#[julia]
Rust dependencies can be declared inline with // cargo-deps: or fenced cargo blocks. The first build may need network access.
@rust_crate loads a Rust crate and returns a Julia module-like binding object.
using RustCall
const MyCrate = @rust_crate "/path/to/my_crate"
MyCrate.add(Int32(1), Int32(2)) # 3For crate-side bindings, use the companion juliacall_macros crate and mark exported items with #[julia].
- Documentation: https://atelierarith.github.io/RustCall.jl
- Examples:
examples/ - Tutorial source:
docs/src/tutorial.md - API reference source:
docs/src/api.md(index) anddocs/src/reference/(one page per group of source files) - Troubleshooting source:
docs/src/troubleshooting.md
For a local checkout:
julia --project -e 'using Pkg; Pkg.instantiate()'
julia --project -e 'using Pkg; Pkg.build("RustCall")'
julia --project -e 'using Pkg; Pkg.test()'
julia --project=docs docs/make.jlThe main package entry point is src/RustCall.jl. Runnable examples live in examples/.
RustCall.jl has been implemented with support from AI coding tools and agents including Codex, Claude Code, and Cursor.