| Crates.io | autozig |
| lib.rs | autozig |
| version | 0.1.2 |
| created_at | 2026-01-05 09:05:40.019505+00 |
| updated_at | 2026-01-06 02:33:16.373319+00 |
| description | Safe autogenerated interop between Rust and Zig |
| homepage | https://github.com/layola13/autozig |
| repository | https://github.com/layola13/autozig |
| max_upload_size | |
| id | 2023448 |
| size | 508,086 |

AutoZig enables safe, ergonomic interop between Rust and Zig code, inspired by autocxx for C++.
Quick Start • Features • Phase 4: Advanced Features • Documentation • Examples • Contributing
🛡️ Safety FirstZero ⚡ PerformanceCompile-time code generation - Zig code is compiled during |
🔒 Type SafetyAutomatic type conversion - Safe bindings between Rust and Zig types 🚀 Developer ExperienceWrite Zig inline - Embed Zig code directly in your Rust files |
# Cargo.toml
[dependencies]
autozig = "0.1"
[build-dependencies]
autozig-build = "0.1"
// build.rs
fn main() -> anyhow::Result<()> {
autozig_build::build("src")?;
Ok(())
}
// src/main.rs
use autozig::autozig;
autozig! {
// Zig implementation
const std = @import("std");
export fn compute_hash(ptr: [*]const u8, len: usize) u64 {
const data = ptr[0..len];
var hash: u64 = 0;
for (data) |byte| {
hash +%= byte;
}
return hash;
}
---
// Rust signatures (optional - enables safe wrappers)
fn compute_hash(data: &[u8]) -> u64;
}
fn main() {
let data = b"Hello AutoZig";
let hash = compute_hash(data); // Safe call, no unsafe!
println!("Hash: {}", hash);
}
Latest Release - AutoZig now supports WebAssembly with Zig + Rust static linking for extreme performance in browsers!
Compile Zig and Rust into a single WASM file with zero-copy memory sharing:
use wasm_bindgen::prelude::*;
use autozig::autozig;
autozig! {
// Zig code compiled to WASM
export fn invert_colors(ptr: [*]u8, len: usize) void {
var i: usize = 0;
while (i < len) : (i += 4) {
ptr[i] = 255 - ptr[i]; // R
ptr[i+1] = 255 - ptr[i+1]; // G
ptr[i+2] = 255 - ptr[i+2]; // B
}
}
---
fn invert_colors(data: &mut [u8]);
}
#[wasm_bindgen]
pub fn apply_filter(mut data: Vec<u8>) -> Vec<u8> {
invert_colors(&mut data); // Zero-copy call to Zig
data
}
Features:
.wasm file@Vector + WASM SIMD128 instructions-O ReleaseFast + wasm-optReal-World Performance (Image Filter Benchmark - 2.1 MB image):
| Implementation | Processing Time | Throughput | Relative Performance |
|---|---|---|---|
| ⚡ AutoZig (Zig SIMD) | 0.80 ms | 2631.84 MB/s | Baseline (1.00x) |
| 🦀 Rust Native | 2.50 ms | 842.19 MB/s | 3.13x slower |
| 🟨 JavaScript | 3.80 ms | 554.07 MB/s | 4.75x slower |
Why AutoZig is faster:
@Vector(16, u8) compiles to v128.load/sub/store+| and -| operationsBuild for WASM:
rustup target add wasm32-unknown-unknown
cargo install wasm-pack
wasm-pack build --target web
📖 Learn More: examples/wasm_filter | docs/PHASE_5_WASM_DESIGN.md
Latest Release - AutoZig Phase 1-4 fully complete! New Stream support, zero-copy optimization, SIMD detection and more advanced features!
异步数据流支持,基于 futures::Stream trait:
use autozig::stream::create_stream;
use futures::StreamExt;
let (tx, stream) = create_stream::<U32Value>();
futures::pin_mut!(stream);
while let Some(result) = stream.next().await {
println!("Received: {:?}", result);
}
Features:
futures::Stream trait implementationZero-copy buffer passing for efficient Zig → Rust data transfer with no overhead:
use autozig::zero_copy::ZeroCopyBuffer;
// Zig generates data, Rust receives with zero-copy
let buffer = ZeroCopyBuffer::from_zig_vec(raw_vec);
let data = buffer.into_vec(); // Zero-copy conversion
Performance:
Compile-time SIMD feature detection and automatic optimization:
// build.rs
let simd_config = autozig_build::detect_and_report();
println!("Detected SIMD: {}", simd_config.description);
Supported Features:
📖 Learn More: examples/stream_basic | examples/zero_copy | examples/simd_detect
AutoZig supports generic monomorphization and async FFI!
Write generic Rust functions and let AutoZig generate type-specific Zig implementations:
use autozig::autozig;
autozig! {
// Zig implementations for each type
export fn sum_i32(data_ptr: [*]const i32, data_len: usize) i32 {
var total: i32 = 0;
var i: usize = 0;
while (i < data_len) : (i += 1) {
total += data_ptr[i];
}
return total;
}
export fn sum_f64(data_ptr: [*]const f64, data_len: usize) f64 {
var total: f64 = 0.0;
var i: usize = 0;
while (i < data_len) : (i += 1) {
total += data_ptr[i];
}
return total;
}
---
// Declare once, use with multiple types!
#[monomorphize(i32, f64, u64)]
fn sum<T>(data: &[T]) -> T;
}
fn main() {
let ints = vec![1i32, 2, 3, 4, 5];
let floats = vec![1.5f64, 2.5, 3.5];
println!("Sum of ints: {}", sum_i32(&ints)); // 15
println!("Sum of floats: {}", sum_f64(&floats)); // 7.5
}
Features:
process<T> → process_i32, process_f64)&[T], &mut [T], nested types)Write async Rust APIs backed by synchronous Zig implementations:
use autozig::include_zig;
include_zig!("src/compute.zig", {
// Declare async functions
async fn heavy_computation(data: i32) -> i32;
async fn process_data(input: &[u8]) -> usize;
});
#[tokio::main]
async fn main() {
// Async API - automatically uses tokio::spawn_blocking
let result = heavy_computation(42).await;
println!("Result: {}", result);
// Concurrent execution
let tasks = vec![
tokio::spawn(async { heavy_computation(10).await }),
tokio::spawn(async { heavy_computation(20).await }),
tokio::spawn(async { heavy_computation(30).await }),
];
let results = futures::future::join_all(tasks).await;
println!("Concurrent results: {:?}", results);
}
Zig side (stays synchronous!):
// src/compute.zig
export fn heavy_computation(data: i32) i32 {
// Write normal synchronous Zig code
// No async/await needed!
return data * 2;
}
Features:
tokio::spawn_blocking📖 Learn More: examples/generics | examples/async
🎉 Run Zig unit tests as part of your Rust test suite!
AutoZig integrates Zig unit tests into the Rust test framework!
// build.rs
fn main() -> anyhow::Result<()> {
autozig_build::build("src")?;
autozig_build::build_tests("zig")?; // Compile Zig tests
Ok(())
}
// zig/math.zig
export fn factorial(n: u32) u64 {
// ... implementation
}
test "factorial basic cases" {
try std.testing.expectEqual(@as(u64, 120), factorial(5));
}
// tests/zig_tests.rs
#[test]
fn test_math_zig_tests() {
let test_exe = get_test_exe_path("math");
let output = Command::new(&test_exe).output().unwrap();
assert!(output.status.success());
}
Run tests:
cargo test # Automatically runs Rust and Zig tests
📖 Learn More: docs/ZIG_TEST_INTEGRATION.md
🌐 Seamless integration with existing C libraries through Zig wrappers
AutoZig supports calling C functions through Zig wrappers for Rust → Zig → C three-way interoperability:
// build.rs - Add C source files
use autozig_gen_build::Builder;
fn main() {
Builder::new()
.with_c_sources(&["src/math.c", "src/utils.c"])
.build()
.expect("Failed to build");
}
// wrapper.zig - Zig wraps C functions
extern "c" fn c_add(a: i32, b: i32) i32;
export fn add(a: i32, b: i32) i32 {
return c_add(a, b);
}
// main.rs - Rust calls through autozig
use autozig::zig;
zig! {
fn add(a: i32, b: i32) -> i32;
}
fn main() {
println!("{}", add(10, 20)); // Calls C through Zig
}
Benefits:
📖 Complete Example: examples/zig-c
📁 Import external
.zigfiles into your Rust project
Use the include_zig! macro to reference external .zig files:
use autozig::include_zig;
include_zig!("zig/math.zig", {
fn factorial(n: u32) -> u64;
fn fibonacci(n: u32) -> u64;
});
fn main() {
println!("5! = {}", factorial(5));
println!("fib(10) = {}", fibonacci(10));
}
🔄 Automatic conversion between Rust high-level types and Zig FFI-compatible types
| Rust Type | Zig Signature | Auto Conversion |
|---|---|---|
&str |
[*]const u8, usize |
✅ |
&[T] |
[*]const T, usize |
✅ |
&mut [T] |
[*]T, usize |
✅ |
String |
[*]const u8, usize |
✅ |
Implement Rust traits with Zig backends
autozig! {
export fn calculator_add(a: i32, b: i32) i32 { return a + b; }
---
trait Calculator {
fn add(&self, a: i32, b: i32) -> i32 => calculator_add;
}
}
let calc = Calculator::default();
assert_eq!(calc.add(2, 3), 5);
autozig! {
export fn hasher_new() *anyopaque { /* ... */ }
export fn hasher_update(ptr: *anyopaque, data: [*]const u8, len: usize) void { /* ... */ }
export fn hasher_finalize(ptr: *anyopaque) u64 { /* ... */ }
export fn hasher_destroy(ptr: *anyopaque) void { /* ... */ }
---
trait Hasher opaque {
fn new() -> Self => hasher_new;
fn update(&mut self, data: &[u8]) => hasher_update;
fn finalize(&self) -> u64 => hasher_finalize;
fn destroy(self) => hasher_destroy;
}
}
📖 Learn More: docs/TRAIT_SUPPORT_DESIGN.md
All examples are fully tested and ready to run:
include_zig!🎉 NEW! AutoZig now supports full C + Zig + Rust three-way interoperability!
The zig-c example demonstrates a complete calling chain: Rust → Zig → C
use autozig::zig;
zig! {
// Zig wraps C functions and adds enhancements
fn add(a: i32, b: i32) -> i32; // C: c_add()
fn power(base: i32, exp: u32) -> i32; // Zig: uses c_multiply()
fn sum_array(arr: &[i32]) -> i32; // C: c_sum_array()
fn average(arr: &[i32]) -> f64; // Hybrid: C sum + Zig float math
}
fn main() {
// All tests passing: 4/4 unit tests ✅
println!("{}", add(10, 20)); // 30
println!("{}", power(2, 10)); // 1024
println!("{}", sum_array(&[1,2,3,4,5])); // 15
println!("{}", average(&[1,2,3,4,5])); // 3.0
}
Key Features:
&[i32] and &str automatically converted to ptr + lenbuild.rs with with_c_sources() APIArchitecture:
Rust (safe API)
↓ FFI call
Zig (wrapper + enhancements)
↓ extern "c"
C (low-level implementation)
📖 Learn More: examples/zig-c/README.md
Run all examples at once:
cd examples
./verify_all.sh
Output:
======================================
Verification Results Summary
======================================
Total: 15 examples (14 standard + 1 WASM)
Success: 15
Failed: 0
Skipped: 0
[✓] All examples verified successfully! 🎉
📖 Learn More: examples/README.md
AutoZig follows a three-stage pipeline for seamless Rust-Zig interop:
┌─────────────┐
│ Rust Code │
│ with │
│ autozig! │
└──────┬──────┘
│
▼
┌─────────────────────────────────────────┐
│ Stage 1: Parsing (Compile Time) │
│ ───────────────────────────────── │
│ • Scan .rs files for autozig! macros │
│ • Extract Zig code │
│ • Parse Rust signatures │
│ • Detect generics & async │
└──────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Stage 2: Build (build.rs) │
│ ────────────────────────────── │
│ • Compile Zig → static library (.a) │
│ • Generate monomorphized versions │
│ • Link with Rust binary │
└──────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Stage 3: Macro Expansion │
│ ──────────────────────────── │
│ • Generate safe Rust wrappers │
│ • Handle &str → (ptr, len) conversion │
│ • Generate async spawn_blocking │
│ • Include FFI bindings │
└──────┬──────────────────────────────────┘
│
▼
┌─────────────┐
│ Safe Rust │
│ API │
└─────────────┘
autozig/
├── src/lib.rs # Main library
├── parser/ # Macro input parser
│ └── src/lib.rs # Parse generics & async
├── macro/ # Procedural macro
│ └── src/lib.rs # Code generation (Phase 3)
├── engine/ # Core build engine
│ ├── scanner.rs # Source code scanner
│ ├── zig_compiler.rs # Zig compiler wrapper
│ └── type_mapper.rs # Type conversion logic
├── gen/build/ # Build script helpers
├── examples/ # 14 working examples
│ ├── verify_all.sh # Batch verification script
│ └── README.md # Examples documentation
└── docs/ # Technical documentation
|
| Component | Version | Notes |
|---|---|---|
| Rust | 1.77+ | Workspace features required |
| Zig | 0.11+ or 0.12+ | Must be in PATH |
| Tokio | 1.0+ | Required for async examples |
| Feature | autocxx (C++) | autozig (Zig) |
|---|---|---|
| Target Language | C++ | Zig |
| Binding Generator | bindgen + cxx | bindgen |
| Safe Wrappers | ✅ | ✅ |
| Inline Code | ❌ | ✅ |
| Generics Support | ✅ | ✅ |
| Async Support | ❌ | ✅ |
| Stream Support | ❌ | ✅ |
| Zero-Copy | ❌ | ✅ |
| SIMD Optimization | ❌ | ✅ |
| Build Complexity | High | Medium |
| Type Safety | Strong | Strong |
| Zig Type | Rust Type | Notes |
|---|---|---|
i8, i16, i32, i64 |
i8, i16, i32, i64 |
✅ Direct mapping |
u8, u16, u32, u64 |
u8, u16, u32, u64 |
✅ Direct mapping |
f32, f64 |
f32, f64 |
✅ Direct mapping |
bool |
u8 |
⚠️ Zig bool is u8 in C ABI |
[*]const u8 |
*const u8 |
🔧 Raw pointer |
[*]const u8 + len |
&[u8] |
🛡️ With safe wrapper |
Contributions are welcome! This is an experimental project exploring Rust-Zig interop.
Ways to contribute:
Licensed under either of:
at your option.
✅ Phase 1-5 Complete! - AutoZig 全功能完成,支持 WebAssembly!
Current Status:
- ✅ Phase 1: Basic FFI bindings (100%)
- ✅ Phase 2: Smart Lowering & Traits (100%)
- ✅ Phase 3: Generics & Async (100%)
- ✅ Phase 4: Stream, Zero-Copy & SIMD (100%)
- ✅ Phase 5: WebAssembly Support (100%) 🌐
Statistics:
- 📦 15 working examples
- ✅ 39/39 tests passing (100%)
- 📝 22+ documentation files
- 🌐 Full WASM support with static linking
- 🚀 Production ready
Made with ❤️ for the Rust and Zig communities