# 帳票設計書 12-to msgpackz

## 概要

本ドキュメントは、Nushellの`to msgpackz`コマンドの設計仕様を定義する帳票設計書である。このコマンドは、Nu値をBrotli圧縮されたMessagePack形式のバイナリデータに変換する機能を提供する。

### 本帳票の処理概要

`to msgpackz`コマンドは、Nushellのあらゆるデータ型をMessagePack形式でシリアライズした後、Brotli圧縮を適用してコンパクトなバイナリデータを生成するコマンドである。通常のMessagePack形式よりもさらに高い圧縮率を実現し、特にプラグインレジストリファイル（`$nu.plugin-path`）で使用されるフォーマットである。

**業務上の目的・背景**：大規模なデータ構造や設定ファイルを保存する際、ディスク容量の節約やI/O効率の向上が求められる。Brotli圧縮を組み合わせることで、MessagePack形式をさらにコンパクトにし、ストレージ効率を最大化できる。特にNushellのプラグインレジストリでは、多数のプラグイン情報を効率的に保存するためにこの形式が採用されている。

**帳票の利用シーン**：プラグインレジストリの保存、大規模設定データのアーカイブ、帯域幅が限られた環境でのデータ転送、長期保存用のデータシリアライズに利用される。

**主要な出力内容**：
1. 入力値のMessagePack形式バイナリをBrotli圧縮したデータ
2. 圧縮品質（quality）と窓サイズ（window-size）のカスタマイズ
3. 日時型の拡張型によるシリアライズ（to msgpackと同様）

**帳票の出力タイミング**：パイプライン内で`to msgpackz`コマンドが実行されたとき、入力データが即座にBrotli圧縮MessagePackバイナリに変換されて出力される。

**帳票の利用者**：Nushellユーザー、プラグイン開発者、システム管理者、データアーカイブ担当者

## 帳票種別

データ変換出力（圧縮バイナリ形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Nushellコマンドライン | - | `to msgpackz`コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | Brotli圧縮MessagePack |
| 用紙サイズ | N/A（バイナリデータ） |
| 向き | N/A |
| ファイル名 | 任意（リダイレクト先に依存、プラグインレジストリでは`$nu.plugin-path`） |
| 出力方法 | 標準出力（パイプライン） |
| 文字コード | バイナリ |

### Brotli圧縮固有設定

| 項目 | 内容 | デフォルト値 |
|-----|------|-------------|
| バッファサイズ | 65536バイト | 固定 |
| 圧縮品質（quality） | 0-11 | 3 |
| 窓サイズ（window-size） | 10-24 | 20 |

## 帳票レイアウト

### レイアウト概要

圧縮バイナリ形式のため、視覚的なレイアウトは存在しない。データは以下の2段階で変換される。

```
┌─────────────────────────────────────┐
│          入力データ（Nu値）           │
└───────────────┬─────────────────────┘
                │ MessagePackシリアライズ
                ▼
┌─────────────────────────────────────┐
│       MessagePackバイナリ            │
└───────────────┬─────────────────────┘
                │ Brotli圧縮
                ▼
┌─────────────────────────────────────┐
│     Brotli圧縮バイナリストリーム      │
└─────────────────────────────────────┘
```

### コマンドオプション

| No | オプション | 短縮形 | 型 | 説明 |
|----|-----------|-------|-----|------|
| 1 | --quality | -q | Int | Brotli圧縮品質（0-11、デフォルト3） |
| 2 | --window-size | -w | Int | Brotli窓サイズ（10-24、デフォルト20） |
| 3 | --serialize | -s | Switch | 非復元型を文字列としてシリアライズ |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 入力値 | 任意のNu値 | Yes |
| --quality | 圧縮品質レベル | No（デフォルト: 3） |
| --window-size | 圧縮窓サイズ | No（デフォルト: 20） |
| --serialize | クロージャ等の非復元型をシリアライズ | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| - | N/A（入力順序を維持） | - |

### 改ページ条件

N/A（バイナリストリーム出力）

## データベース参照仕様

### 参照テーブル一覧

N/A（ファイルシステム/データベースを参照しない）

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| quality変換 | u32::try_from(i64) | - | 負の値はエラー |
| window-size変換 | u32::try_from(i64) | - | 負の値はエラー |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[to msgpackz実行] --> B[オプション解析]
    B --> C{quality指定?}
    C -->|Yes| D[quality値検証]
    C -->|No| D2[デフォルト quality=3]
    D --> E{window-size指定?}
    D2 --> E
    E -->|Yes| F[window-size値検証]
    E -->|No| F2[デフォルト window-size=20]
    F --> G[入力値取得]
    F2 --> G
    G --> H[CompressorWriter作成]
    H --> I[write_value呼び出し]
    I --> J[Brotliストリームflush]
    J --> K[バイナリ出力]
    K --> L[PipelineData返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 型変換エラー | qualityが負の値またはu32範囲外 | "can't convert int to u32" | 0-11の範囲を指定 |
| 型変換エラー | window-sizeが負の値またはu32範囲外 | "can't convert int to u32" | 10-24の範囲を指定 |
| 深度超過 | ネストが50階層を超えた | "MessagePack data is nested too deeply" | データ構造を簡素化 |
| 非サポート型 | Closureを--serializeなしで変換 | "closures are currently not deserializable" | --serializeオプションを使用 |
| IOエラー | 圧縮/書き込み失敗 | IOエラーメッセージ | 出力先を確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 制限なし（メモリに依存） |
| 目標出力時間 | N/A（データサイズと圧縮品質に比例） |
| 同時出力数上限 | 1（シングルパイプライン） |
| 圧縮バッファサイズ | 65536バイト（固定） |

## セキュリティ考慮事項

- クロージャをシリアライズする場合、コード内容が圧縮データ内に含まれる
- 圧縮により内容の直接確認は困難だが、解凍により復元可能
- パスワード保護機能は提供されない

## 備考

- プラグインレジストリファイル（`$nu.plugin-path`）で使用されるフォーマット
- Brotli圧縮ライブラリ（brotliクレート）を使用
- 内部的に`to msgpack`と同じwrite_value関数を共有

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

`to msgpack`と同じValue型が対象となる。圧縮パラメータの理解が重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | msgpackz.rs | `crates/nu-command/src/formats/to/msgpackz.rs` | 定数定義（BUFFER_SIZE, DEFAULT_QUALITY, DEFAULT_WINDOW_SIZE） |

**読解のコツ**: 8-10行目の定数定義を確認し、デフォルト値を把握する。

#### Step 2: エントリーポイントを理解する

処理の起点となるコマンド実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | msgpackz.rs | `crates/nu-command/src/formats/to/msgpackz.rs` | ToMsgpackzコマンドの実装 |

**主要処理フロー**:
1. **15-41行目**: Command traitの実装、シグネチャ定義（quality, window-size, serialize）
2. **51-102行目**: run関数でオプション解析、Brotli CompressorWriter作成
3. **89-96行目**: write_value呼び出し（msgpack.rsからインポート）

#### Step 3: 圧縮処理を理解する

Brotli圧縮の適用箇所を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | msgpackz.rs | `crates/nu-command/src/formats/to/msgpackz.rs` | CompressorWriter使用箇所 |

**主要処理フロー**:
- **82-87行目**: brotli::CompressorWriter::new()でラッパー作成
- **89-96行目**: write_valueでMessagePackデータを圧縮ストリームに書き込み
- **97-99行目**: flush()で残データを出力、dropでリソース解放

#### Step 4: 共有ロジックを理解する

`to msgpack`と共有するwrite_value関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | msgpack.rs | `crates/nu-command/src/formats/to/msgpack.rs` | write_value関数（161-299行目） |

### プログラム呼び出し階層図

```
ToMsgpackz::run (msgpackz.rs:51)
    │
    ├─ call.get_flag("quality") - 圧縮品質取得
    ├─ call.get_flag("window-size") - 窓サイズ取得
    ├─ call.has_flag("serialize") - シリアライズフラグ
    │
    ├─ input.into_value() - パイプライン入力を値に変換
    │
    ├─ brotli::CompressorWriter::new() - 圧縮ライター作成
    │       │
    │       └─ パラメータ: buffer_size, quality, window_size
    │
    └─ msgpack::write_value() - MessagePackシリアライズ（共有関数）
            │
            ├─ 型ごとの変換処理
            └─ 圧縮ストリームへの書き込み
```

### データフロー図

```
[入力]                    [処理]                         [出力]

PipelineData ───▶ into_value() ───▶ Value
                                        │
                                        ▼
                           CompressorWriter作成
                           (quality, window_size)
                                        │
                                        ▼
                              write_value()
                                        │
                                        ▼
                           Brotliストリームに書き込み
                                        │
                                        ▼
                                   flush()
                                        │
                                        ▼
                              Vec<u8> (圧縮バイナリ)
                                        │
                                        ▼
                            Value::binary() ───▶ PipelineData
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| msgpackz.rs | `crates/nu-command/src/formats/to/msgpackz.rs` | ソース | to msgpackzコマンドの実装 |
| msgpack.rs | `crates/nu-command/src/formats/to/msgpack.rs` | ソース | write_value関数の定義元 |
| msgpackz.rs | `crates/nu-command/tests/format_conversions/msgpackz.rs` | テスト | 変換テストケース |
| brotli (crate) | 外部クレート | 依存 | Brotli圧縮実装 |
| rmp (crate) | 外部クレート | 依存 | MessagePackエンコード実装 |
