# 帳票設計書 11-to msgpack

## 概要

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

### 本帳票の処理概要

`to msgpack`コマンドは、Nushellのあらゆるデータ型（テーブル、レコード、リスト、基本型など）をMessagePack形式のバイナリデータに変換するコマンドである。MessagePackは、JSONと同様のデータ構造を持ちながら、よりコンパクトなバイナリ形式で表現できる効率的なシリアライゼーション形式である。

**業務上の目的・背景**：データのシリアライゼーションにおいて、テキスト形式（JSON、YAML等）よりも高速かつコンパクトなバイナリ形式が必要な場面がある。特に、大量データの保存、ネットワーク転送、外部システムとの連携において、MessagePack形式は有効な選択肢となる。本コマンドにより、Nushell内で処理したデータを効率的にシリアライズし、他システムと連携することが可能となる。

**帳票の利用シーン**：データのバイナリ保存、外部API連携時のデータ送信、プラグインレジストリとのデータ交換、大規模データセットのコンパクトな保存、およびパフォーマンスが重要な場面でのデータ交換に利用される。

**主要な出力内容**：
1. 入力値のMessagePack形式バイナリ表現
2. 日時型の拡張型（Extension Type）によるシリアライズ
3. ネストされたデータ構造の再帰的な変換

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

**帳票の利用者**：Nushellユーザー、シェルスクリプト開発者、データエンジニア、システム連携担当者

## 帳票種別

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

## 利用画面

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

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | MessagePack (application/x-msgpack) |
| 用紙サイズ | N/A（バイナリデータ） |
| 向き | N/A |
| ファイル名 | 任意（リダイレクト先に依存） |
| 出力方法 | 標準出力（パイプライン） |
| 文字コード | バイナリ |

### MessagePack固有設定

| 項目 | 内容 |
|-----|------|
| 日時拡張型 | タイプID -1（Timestamp Extension） |
| 最大再帰深度 | 50 |
| シリアライズフラグ | `--serialize`オプションで非復元型をシリアライズ可能 |

## 帳票レイアウト

### レイアウト概要

MessagePackはバイナリ形式のため、視覚的なレイアウトは存在しない。データは以下のMessagePack型にマッピングされる。

```
┌─────────────────────────────────────┐
│      MessagePackバイナリストリーム    │
│  ┌─────────────────────────────────┐│
│  │ マーカー | データ | マーカー | ...││
│  └─────────────────────────────────┘│
└─────────────────────────────────────┘
```

### 型マッピング

| No | Nu型 | MessagePack型 | 説明 |
|----|------|---------------|------|
| 1 | Bool | Boolean | true/false |
| 2 | Int | Integer (sint) | 符号付き整数 |
| 3 | Float | Float64 | 64ビット浮動小数点数 |
| 4 | Filesize | Integer (sint) | バイト数として整数化 |
| 5 | Duration | Integer (sint) | ナノ秒として整数化 |
| 6 | Date | Extension (type -1) | 32ビットまたは96ビットタイムスタンプ |
| 7 | Range | Array | リストに展開 |
| 8 | String | String | UTF-8文字列 |
| 9 | Glob | String | パターン文字列 |
| 10 | Record | Map | キー・値ペア |
| 11 | List | Array | 配列 |
| 12 | Nothing | Nil | null値 |
| 13 | Binary | Binary | バイナリデータ |
| 14 | CellPath | Array | 文字列/整数の配列 |
| 15 | Custom | (基本型に変換) | カスタム値は基本型に変換 |
| 16 | Closure | String (要--serialize) | 文字列表現 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 入力値 | 任意のNu値 | Yes |
| --serialize | クロージャ等の非復元型をシリアライズ | No |

### ソート順

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

### 改ページ条件

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

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

### 参照テーブル一覧

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

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 日時32ビット判定 | timestamp >= 0 && timestamp < u32::MAX && subsec_nanos == 0 | - | 条件を満たす場合32ビット形式 |
| 日時96ビット形式 | 32ビットナノ秒 + 64ビット秒 | - | 32ビット条件を満たさない場合 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[to msgpack実行] --> B[入力値取得]
    B --> C{--serializeフラグ?}
    C -->|Yes| D[シリアライズモード有効]
    C -->|No| D2[通常モード]
    D --> E[write_value呼び出し]
    D2 --> E
    E --> F{値の型判定}
    F -->|Bool| G1[write_bool]
    F -->|Int| G2[write_sint]
    F -->|Float| G3[write_f64]
    F -->|Date| G4[タイムスタンプ拡張型]
    F -->|Record| G5[write_map_len + 再帰]
    F -->|List| G6[write_array_len + 再帰]
    F -->|Closure| G7{serialize?}
    G7 -->|Yes| H1[文字列化]
    G7 -->|No| H2[エラー]
    G1 --> I[バイナリ出力]
    G2 --> I
    G3 --> I
    G4 --> I
    G5 --> I
    G6 --> I
    H1 --> I
    I --> J[メタデータ付与]
    J --> K[PipelineData返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 深度超過 | ネストが50階層を超えた | "MessagePack data is nested too deeply" | データ構造を簡素化 |
| 非サポート型 | Closureを--serializeなしで変換 | "closures are currently not deserializable" | --serializeオプションを使用 |
| 値変換エラー | u32への変換失敗等 | "Value not compatible with MessagePack" | 入力値を確認 |
| IOエラー | 書き込み失敗 | IOエラーメッセージ | 出力先を確認 |

## パフォーマンス要件

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

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

- クロージャをシリアライズする場合、コード内容が文字列として出力される可能性がある
- 出力バイナリにはソースコードのスパン情報は含まれない
- パスワード保護機能は提供されない

## 備考

- MessagePackフォーマット仕様: https://msgpack.org/
- タイムスタンプ拡張型はMessagePack標準仕様に準拠
- 元のアイデアはnu_plugin_msgpackプラグインに基づく

---

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

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

### 推奨読解順序

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

MessagePack変換の対象となるNu値の型定義を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-protocol/src/value/mod.rs` | Value enumの各バリアントがMessagePackにマッピングされる対象 |

**読解のコツ**: RustのValue enumを確認し、各型がどのようにシリアライズされるかの概観を掴む。

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

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

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

**主要処理フロー**:
1. **17-104行目**: Command traitの実装、シグネチャ定義
2. **75-103行目**: run関数でパイプライン入力を受け取り、write_valueを呼び出し
3. **161-299行目**: write_value関数で型ごとの変換ロジック

#### Step 3: 型変換ロジックを理解する

各Nu型からMessagePack型への変換処理の詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | msgpack.rs | `crates/nu-command/src/formats/to/msgpack.rs` | write_value関数内のmatch式 |

**主要処理フロー**:
- **176-180行目**: Bool型の変換
- **181-191行目**: 数値型（Int, Float, Filesize, Duration）の変換
- **193-209行目**: Date型のタイムスタンプ拡張型への変換
- **227-233行目**: Record型のMap形式への変換
- **234-246行目**: List型のArray形式への変換
- **252-266行目**: Closure型の条件付きシリアライズ

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

```
ToMsgpack::run (msgpack.rs:75)
    │
    ├─ input.into_value() - パイプライン入力を値に変換
    │
    └─ write_value() (msgpack.rs:161)
           │
           ├─ mp::write_bool() - Bool値
           ├─ mp::write_sint() - 整数値
           ├─ mp::write_f64() - 浮動小数点
           ├─ mp::write_ext_meta() - 日時拡張型
           ├─ mp::write_str() - 文字列
           ├─ mp::write_map_len() + 再帰 - レコード
           ├─ mp::write_array_len() + 再帰 - リスト
           ├─ mp::write_nil() - Nothing
           ├─ mp::write_bin() - バイナリ
           └─ val.to_base_value() + 再帰 - カスタム値
```

### データフロー図

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

PipelineData ───▶ into_value() ───▶ Value
                                        │
                                        ▼
                               write_value()
                                        │
                          ┌─────────────┼─────────────┐
                          ▼             ▼             ▼
                       Bool型       Record型      List型
                          │             │             │
                          ▼             ▼             ▼
                    mp::write_*   mp::write_map  mp::write_array
                          │             │             │
                          └─────────────┴─────────────┘
                                        │
                                        ▼
                                Vec<u8> (バイナリ)
                                        │
                                        ▼
                            Value::binary() ───▶ PipelineData
                                                (metadata: application/x-msgpack)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| msgpack.rs | `crates/nu-command/src/formats/to/msgpack.rs` | ソース | to msgpackコマンドの実装 |
| msgpack.rs | `crates/nu-command/src/formats/from/msgpack.rs` | ソース | from msgpackコマンド（逆変換） |
| msgpack.rs | `crates/nu-command/tests/format_conversions/msgpack.rs` | テスト | 変換テストケース |
| mod.rs | `crates/nu-protocol/src/value/mod.rs` | ソース | Value型定義 |
| rmp (crate) | 外部クレート | 依存 | MessagePackエンコード実装 |
