> ## 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.

# Rust で拡張機能を作成する

> VillageSQL Rust SDK を使い始める — 安全な Rust で拡張関数を記述し、VEB ファイルとしてパッケージ化し、VillageSQL にインストールします。

> [!NOTE]
>
> C++ を使用する場合は、[C++ で拡張機能を作成する](https://villagesql.com/docs/ja/extensions/build/create.md) を参照して、C++ SDK の手順を確認してください。

VillageSQL 拡張機能は、`villagesql` クレートを使用して Rust で記述できます。SDK はすべての FFI マーシャリングを処理します。通常の Rust 型で作業し、`extension!` マクロが、ロード時にサーバーから呼び出される C エントリポイントを生成します。

## 前提条件

始める前に、VillageSQL をソースからビルドしてください。`cargo vsql install` と `cargo vsql test` はサーバーのビルドツリーを使用します。まず [ソースからビルドする](https://villagesql.com/docs/ja/8.4/stable/source.md) ガイドに従ってください。

次のものも必要です。

* **Rust の安定版ツールチェーン** — [rustup.rs](https://rustup.rs) にてインストール
* **Git** — SDK と拡張機能リポジトリをクローンするため
* **cargo-vsql** — 拡張機能をパッケージ化、インストール、およびテストするための Cargo サブコマンド
* **VillageSQL のビルドディレクトリ** — `cargo vsql install` および `cargo vsql test` のために `VillageSQL_BUILD_DIR` をサーバーのビルドパスに設定します
* **Rust の基礎知識** — Cargo、列挙型、およびパターンマッチングに慣れていること

SDK リポジトリから `cargo-vsql` をインストールします。

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

利用可能であることを確認します。

```bash theme={null}
cargo vsql --help
```

## 新しいクレートを作成する

新しい Rust ライブラリクレートを作成し、SDK を追加します。

```bash theme={null}
cargo new --lib vsql_rot13
cd vsql_rot13
cargo add villagesql
```

次に、`Cargo.toml` でクレートのタイプを設定します。

```toml theme={null}
[lib]
crate-type = ["cdylib"]
```

`cdylib` クレートタイプは、Cargo に共有ライブラリ（Linux では `.so`、macOS では `.dylib`）を生成するように指示し、サーバーがロードできるようにします。

## 最初の関数を記述する

`src/lib.rs` を完全な拡張機能に置き換えます。

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

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

fn rot13(s: &str) -> String {
    s.chars()
        .map(|c| match c {
            'a'..='m' | 'A'..='M' => (c as u8 + 13) as char,
            'n'..='z' | 'N'..='Z' => (c as u8 - 13) as char,
            _ => c,
        })
        .collect()
}

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

`func!` マクロは、`rot13_impl` を SQL 名 `vsql_rot13` に、`STRING -> STRING` シグネチャで関連付けます。

関数のシグネチャは `fn(&[InValue]) -> VdfReturn` です。`InValue` は、サーバーが渡す SQL 型の列挙型です。`VdfReturn` は、サーバーに返す値です。`args.first()` をチェックして、NULL の場合と、型が間違っている場合の両方を処理してから、値にアクセスします。

関数が同じ入力に対して常に同じ出力を返す場合は、関数を決定論的として宣言します。生成列や `CHECK` 制約で使用できるのは、決定論的な関数だけです。

```rust theme={null}
villagesql::func!(rot13_impl, "vsql_rot13", [villagesql::Type::String] -> villagesql::Type::String, deterministic: true)
```

## manifest.json を追加する

クレートのルート（`Cargo.toml` と同じディレクトリ）に `manifest.json` を作成します。

```json theme={null}
{
  "name": "vsql_rot13",
  "version": "0.1.0",
  "description": "ROT-13 encoding for VillageSQL",
  "author": "Your Name",
  "license": "GPL-2.0"
}
```

サーバーは、インストール時にこれを読み取ります。`name` フィールドは、`Cargo.toml` の `[package]` セクションの `name`、および `INSTALL EXTENSION` に渡すものと一致する必要があります。

## ビルドとインストール

> [!NOTE]
>
> `cargo vsql package`、`cargo vsql install`、および `cargo vsql test` は、拡張機能ディレクトリ（`Cargo.toml` と `manifest.json` がある場所）から実行し、ワークスペースのルートから実行しないでください。

拡張機能を `.veb` ファイルにパッケージ化します。

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

これにより、`dist/vsql_rot13.veb` が生成されます。VEB をパッケージ化して、VillageSQL のビルドディレクトリに直接コピーするには、次のようにします。

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

開発中に依存関係をローカルのチェックアウトにパッチするには、`--config KEY=VALUE` を渡します（繰り返し指定可能）。

```bash theme={null}
cargo vsql install --config 'patch.crates-io.villagesql.path="/path/to/villagesql"'
```

VEB が拡張機能ディレクトリにコピーされていることを確認します。

```bash theme={null}
ls "$VillageSQL_BUILD_DIR/veb_output_directory/"
# vsql_rot13.veb
```

> [!NOTE]
>
> **0.0.8-dev での変更点。** `cargo vsql install` は VEB を `$VillageSQL_BUILD_DIR/lib/veb/` にコピーします。

## テスト

`mysql-test/t/rot13_basic.test` にテストファイルを作成します。

```sql theme={null}
INSTALL EXTENSION vsql_rot13;
SELECT vsql_rot13('Hello');
SELECT vsql_rot13('');
SELECT vsql_rot13(NULL);
UNINSTALL EXTENSION vsql_rot13;
```

期待される結果を生成します。

```bash theme={null}
cargo vsql test --record
```

テストスイートを実行します。

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

関数の動作を変更した場合は、`cargo vsql test --record` を再実行して、期待される結果を更新してから、`cargo vsql test` を実行して確認します。

## SQL でインストールする

VEB が拡張機能ディレクトリに配置されたら、インストールします。

```sql theme={null}
INSTALL EXTENSION vsql_rot13;
```

確認します。

```sql theme={null}
SELECT * FROM INFORMATION_SCHEMA.EXTENSIONS WHERE EXTENSION_NAME = 'vsql_rot13';
```

呼び出します。

```sql theme={null}
SELECT vsql_rot13('Hello, World!');
-- → Uryyb, Jbeyq!
```

## 次のステップ

このウォークスルーでは、スカラー関数を 1 つ作成します。[vsql-rust-sdk](https://github.com/villagesql/vsql-rust-sdk) リポジトリにある 2 つの実例は、代わりに集約関数と可変長引数のサポートを扱っています。

* [`examples/vsql_agg_sum`](https://github.com/villagesql/vsql-rust-sdk/tree/main/examples/vsql_agg_sum) — `agg_func!` で `SUM` を再実装する集約 VDF。グループごとのアキュムレータに対して、個別の `clear`、`accumulate`、`result` コールバックを使用します。
* [`examples/vsql_varargs`](https://github.com/villagesql/vsql-rust-sdk/tree/main/examples/vsql_varargs) — `varargs_func!` で構築された 4 つの可変長引数関数: `str_join`（検証あり、状態あり）、`arg_count`（検証なし、状態なし）、`describe`（検証あり、状態なし、INT/REAL/STRING の混在引数）、および `point_path`（カスタム `point2d` 型に対する可変長引数）。

各例には、完全な `Cargo.toml`、`manifest.json`、および MTR テストが含まれています。

> [card] [Rust でのカスタム型](https://villagesql.com/docs/ja/sdk/rust/custom-types.md)
>
> バイナリストレージ、順序付け、およびハッシュを持つ新しい列型を定義します。

> [card] [Rust API リファレンス](https://villagesql.com/docs/ja/sdk/rust/api-reference.md)
>
> `InValue`、`VdfReturn`、`extension!`、`func!`、および `custom_type!` — すべてのフィールド。

> [card] [Rustにおけるプレビュー機能](https://villagesql.com/docs/ja/sdk/rust/preview-capabilities.md)
>
> ステータス変数、システム変数、バックグラウンドスレッドワーカー、および requires: リストによるキーリングアクセス。

> [card] [C++ SDK（拡張機能の作成）](https://villagesql.com/docs/ja/extensions/build/create.md)
>
> C++ のパス — 型付きラッパー、ビルダー API、および CMake セットアップ。

> [card] [拡張機能のアーキテクチャ](https://villagesql.com/docs/ja/extensions/build/architecture.md)
>
> VEB ファイルのロード方法、ライフサイクルフック、およびシンボルの分離。

> [card] [ネットワーク依存の拡張機能のテスト](https://villagesql.com/docs/ja/sdk/cpp/testing-network.md)
>
> HTTP サーバーや外部リスナーを起動する拡張機能のための MTR ポートパターン — Rust と C++ の拡張機能に等しく適用されます。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.