> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Writing Rust Extensions

> How to write a VillageSQL extension in Rust — when to choose Rust, cargo-vsql setup, writing a function, testing, and installing.

<Card title="VillageSQL is a drop-in replacement for MySQL with extensions." icon="database" href="/mysql-8.4/0.0.4/quickstart">
  All examples in this guide work on VillageSQL. Install Now →
</Card>

VillageSQL extensions can be written in Rust using the `villagesql` crate. The SDK handles all FFI marshaling — you write ordinary Rust, and the `extension!` macro generates the C entry points the server calls at load time.

## When to Choose Rust

Rust is the right choice when:

* You prefer Rust and don't need a C++ codebase
* You want memory safety without a garbage collector
* You're building a new extension and have no existing C++ dependency

If you have an existing C++ codebase or need the most complete custom-type builder API available today, see [Writing C++ Extensions](/guides/cpp-extensions).

<Warning>
  The Rust SDK is at version 0.0.1. The API is stable for extension development but the custom-type builder API is still maturing.
</Warning>

## Prerequisites

You need:

* **Rust stable toolchain** — install at [rustup.rs](https://rustup.rs)
* **cargo-vsql** — the Cargo subcommand for packaging, installing, and testing

Install `cargo-vsql` from the SDK repo:

```bash theme={null}
git clone https://github.com/villagesql/vsql-rust-sdk
cd vsql-rust-sdk
cargo install --path cargo-vsql
```

## Set Up a New Crate

Create a library crate and configure it:

```bash theme={null}
cargo new --lib vsql_my_extension
cd vsql_my_extension
```

Edit `Cargo.toml`:

```toml theme={null}
[package]
name = "vsql_my_extension"
version = "0.1.0"
edition = "2021"

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

[dependencies]
villagesql = "0.0.1"
```

Add `manifest.json` alongside `Cargo.toml`:

```json theme={null}
{
  "name": "vsql_my_extension",
  "version": "0.1.0",
  "description": "My VillageSQL extension",
  "author": "Your Name",
  "license": "GPL-2.0"
}
```

## Write a Function

The [Building Extensions in Rust](/mysql-8.4/0.0.4/rust-sdk) page has the full walkthrough with the ROT-13 example. The short version: implement `fn(&[InValue]) -> VdfReturn`, register it with `func!`, and wrap everything in `extension!`:

```rust theme={null}
use villagesql::{InValue, VdfReturn};

fn my_func_impl(args: &[InValue]) -> VdfReturn {
    match args.first() {
        Some(InValue::String(s)) => VdfReturn::string(s.to_uppercase()),
        Some(InValue::Null) | None => VdfReturn::null(),
        _ => VdfReturn::error("my_func: expected a STRING argument"),
    }
}

villagesql::extension! {
    funcs: [
        villagesql::func!(my_func_impl, "my_func", [villagesql::Type::String] -> villagesql::Type::String),
    ]
}
```

For custom types (binary storage, ordering, hashing), see [Custom Types in Rust](/mysql-8.4/0.0.4/rust-custom-types).

## Test Your Extension

Write a test in `mysql-test/t/basic.test`:

```sql theme={null}
INSTALL EXTENSION vsql_my_extension;
SELECT my_func('hello');
SELECT my_func(NULL);
UNINSTALL EXTENSION vsql_my_extension;
```

Set your VillageSQL build directory, generate expected results, then run:

```bash theme={null}
export VillageSQL_BUILD_DIR=/path/to/villagesql/build
cargo vsql test --record
cargo vsql test
```

A passing run prints `[ pass ]` for each test file.

## Install in SQL

Package and install:

```bash theme={null}
cargo vsql install
```

Then in SQL:

```sql theme={null}
INSTALL EXTENSION vsql_my_extension;
SELECT * FROM INFORMATION_SCHEMA.EXTENSIONS WHERE EXTENSION_NAME = 'vsql_my_extension';
SELECT my_func('hello');
-- → HELLO
```

## See also

* [Building Extensions in Rust](/mysql-8.4/0.0.4/rust-sdk) — full walkthrough with the ROT-13 example, packaging, and testing details
* [Custom Types in Rust](/mysql-8.4/0.0.4/rust-custom-types) — define new column types with binary storage and ordering
* [Rust API Reference](/mysql-8.4/0.0.4/rust-api-reference) — InValue, VdfReturn, and all macros
* [Writing C++ Extensions](/guides/cpp-extensions) — the C++ path for the same task
