avmnif-rs 0.4.1

Safe NIF toolkit for AtomVM written in Rust
Documentation
# avmnif-rs

Safe Rust bindings and utilities for building AtomVM Native Implemented Functions (NIFs) and ports.

## Overview

`avmnif-rs` provides a type-safe, memory-safe foundation for integrating Rust code with AtomVM. It handles the low-level details of AtomVM's term format, atom management, and FFI boundaries, allowing you to focus on your application logic.

## Features

- **Memory-safe term conversion** between Rust types and AtomVM terms
- **Generic atom table operations** that work with any AtomVM context
- **Tagged ADT serialization** for type-safe Erlang-Rust data exchange
- **NIF collection macros** for easy function registration
- **Port communication utilities** for building custom port drivers
- **Comprehensive error handling** with proper Erlang error propagation
- **No-std compatible** core functionality

## Quick Start

Add to your `Cargo.toml`:

```toml
[dependencies]
avmnif-rs = "0.1"

[lib]
crate-type = ["cdylib"]
```

### Basic NIF Example

```rust
use avmnif_rs::{nif_collection, term::*, atom::AtomTableOps};

fn add_numbers(ctx: &mut Context, args: &[Term]) -> NifResult<Term> {
    if args.len() != 2 {
        return Err(NifError::BadArity);
    }
    
    let a = args[0].to_value()?.as_int().ok_or(NifError::BadArg)?;
    let b = args[1].to_value()?.as_int().ok_or(NifError::BadArg)?;
    
    let result = TermValue::int(a + b);
    Ok(Term::from_value(result, &mut ctx.heap)?)
}

fn nif_init(_ctx: &mut Context) {
    // Initialize any resources here
}

nif_collection!(
    math_nifs,
    init = nif_init,
    nifs = [
        ("add", 2, add_numbers),
    ]
);
```

### Tagged ADT Example

```rust
use avmnif_rs::{tagged::TaggedMap, testing::mocks::MockAtomTable};

#[derive(TaggedMap)]
struct SensorReading {
    temperature: f32,
    humidity: f32,
    timestamp: u64,
}

fn main() {
    let table = MockAtomTable::new();
    let reading = SensorReading {
        temperature: 23.5,
        humidity: 45.2,
        timestamp: 1634567890,
    };
    
    // Serialize to Erlang map
    let term = reading.to_tagged_map(&table).unwrap();
    
    // Deserialize back to Rust
    let parsed = SensorReading::from_tagged_map(term, &table).unwrap();
    assert_eq!(parsed.temperature, 23.5);
}
```

## Architecture

### Core Components

- **`term`** - AtomVM term representation and conversion utilities
- **`atom`** - Generic atom table operations and management
- **`tagged`** - Type-safe ADT serialization with discriminator atoms
- **`ports`** - Port communication and lifecycle management
- **`resource`** - Resource type registration and management

### Design Principles

1. **Generic by design** - All operations work with any `AtomTableOps` implementation
2. **Memory safety** - No unsafe code in the public API surface
3. **Error transparency** - All failure modes are explicit and recoverable
4. **Zero-cost abstractions** - Minimal runtime overhead
5. **Testing-first** - Comprehensive test coverage with mock implementations

## Error Handling

All operations return explicit `Result` types with detailed error information:

```rust
pub enum NifError {
    BadArg,           // Invalid argument type or value
    BadArity,         // Wrong number of arguments
    OutOfMemory,      // Memory allocation failed
    SystemLimit,      // System resource limit exceeded
    InvalidTerm,      // Malformed term structure
    Other(&'static str), // Custom error message
}
```

Errors automatically convert to appropriate Erlang error atoms when crossing the FFI boundary.

## Building

The library compiles to a static library (`.a`) that gets linked into AtomVM:

```bash
cargo build --release
```

This produces `target/release/libmy_nifs.a` which can be linked into AtomVM builds.

## Testing

Run the comprehensive test suite:

```bash
cargo test
```

Tests include:
- Mock atom table implementations for isolated testing
- Round-trip serialization validation
- Error condition coverage
- Memory safety verification
- Integration scenarios

## Platform Support

- **Primary**: Linux x86_64, ARM64
- **Secondary**: macOS, Windows (via WSL)
- **Embedded**: Any target supported by AtomVM with `no_std`

## License

MIT

## Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## Minimum Supported Rust Version (MSRV)

Rust 1.70 or later.