# 機能設計書 27-エンコーディング

## 概要

本ドキュメントは、Nushellにおけるエンコーディング機能の設計仕様を記述する。

### 本機能の処理概要

エンコーディング機能は、文字列とバイナリデータ間の相互変換、および各種エンコーディング形式への変換機能を提供する。異なる文字コードを持つファイルの処理、バイナリデータの文字列化、Base64/Hex形式への変換など、データ形式の変換に使用される。

**業務上の目的・背景**：異なるシステム間でのデータ交換では、文字エンコーディングの違いが問題となることがある。Shift-JIS、EUC-JP、UTF-16など様々なエンコーディングのファイルを処理する必要がある。また、バイナリデータをテキスト形式で扱いたい場合にBase64やHex変換が必要となる。

**機能の利用シーン**：
- Shift-JISエンコードのファイルを読み込んでUTF-8に変換する場合
- バイナリデータをBase64形式でエンコードする場合
- 外部コマンドの出力を適切なエンコーディングでデコードする場合
- 16進数表現のデータをバイナリに変換する場合

**主要な処理内容**：
1. `encode` - 文字列を指定エンコーディングのバイナリに変換
2. `decode` - バイナリを指定エンコーディングの文字列に変換
3. `encode hex` - バイナリを16進数文字列に変換（nu-cmd-extra）
4. `decode hex` - 16進数文字列をバイナリに変換（nu-cmd-extra）

**関連システム・外部連携**：encoding_rsクレート、oem_cpクレートによるエンコーディング処理。

**権限による制御**：特になし。すべてのユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 結果表示画面 | コマンド実行結果の表示 |

## 機能種別

データ変換 / エンコーディング

## 入力仕様

### 入力パラメータ

#### encode

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| encoding | String | Yes | エンコーディング名（例: "shift-jis", "euc-jp"） | 有効なエンコーディング名 |
| --ignore-errors / -i | Switch | No | エンコード不可の文字をHTML実体参照に変換 | - |

#### decode

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| encoding | String | No | エンコーディング名（省略時は自動検出） | 有効なエンコーディング名 |

### 入力データソース

パイプライン入力（文字列、バイナリ、ByteStream）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (encode) | Binary | エンコードされたバイナリデータ |
| result (decode) | String | デコードされた文字列 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ encode: 文字列を受け付ける
   └─ decode: バイナリまたはByteStreamを受け付ける
2. エンコーディング名を解析する
   └─ encoding_rsまたはoem_cpのエンコーディングを特定
3. 変換処理を実行
   └─ encode: 文字列 → バイナリ
   └─ decode: バイナリ → 文字列
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{コマンド種別}
    B -->|encode| C[文字列入力確認]
    B -->|decode| D[バイナリ入力確認]
    C --> E[エンコーディング特定]
    D --> F{エンコーディング指定?}
    F -->|Yes| G[指定エンコーディング使用]
    F -->|No| H[自動検出]
    E --> I[encoding_rsでエンコード]
    G --> J[デコード処理]
    H --> J
    I --> K{エラー発生?}
    K -->|Yes, ignore-errors| L[HTML実体参照に変換]
    K -->|No| M[バイナリ出力]
    L --> M
    J --> N[文字列出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-1 | エンコーダ選択 | encoding_rsまたはoem_cpを使用 | 常時 |
| BR-27-2 | OEMコードページ | 数値（例: 437, 850）でOEMコードページを指定可能 | decode使用時 |
| BR-27-3 | エラー処理 | --ignore-errorsでエンコード不可文字をHTML実体参照に変換 | encode使用時 |
| BR-27-4 | UTF-16制限 | encoding_rsはUTF-16エンコーダを提供しない | encode使用時 |

### 計算ロジック

サポートされるエンコーディング例（encoding_rs）：
- big5, euc-jp, euc-kr, gbk
- iso-8859-1, iso-8859-15
- shift_jis (shift-jis)
- utf-16le, utf-16be（デコードのみ）
- cp1252 (windows-1252)

OEMコードページ（oem_cp）：
- 437, 737, 775, 850, 852, 855, 858
- 860, 861, 862, 863, 865, 866

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| GenericError | 不明エンコーディング | 無効なエンコーディング名 | 有効な名前を使用 |
| OnlySupportsThisInputType | 型エラー | 期待しない入力型 | 適切な型を入力 |
| UnsupportedInput | 非サポート入力 | リスト等の非対応入力 | 単一値を入力 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし（ステートレス処理）

## パフォーマンス要件

- encoding_rsクレートによる高速なエンコーディング処理
- ByteStreamからの直接処理でメモリ効率を向上

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

- 不正なバイトシーケンスの処理に注意
- 文字化け防止のため適切なエンコーディング指定が必要

## 備考

- `encode`、`decode`はともに定数式として評価可能（is_const = true）
- encoding_rsドキュメント: https://docs.rs/encoding_rs/latest/encoding_rs/

---

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

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

### 推奨読解順序

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

エンコーディングモジュールの構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-command/src/strings/encode_decode/mod.rs` | モジュール構成 |
| 1-2 | decode.rs | `crates/nu-command/src/strings/encode_decode/decode.rs` | OEM_DECODEテーブル（9-32行目） |

**読解のコツ**: OEM_DECODEはLazyLockで初期化されるHashMap。OEMコードページ番号をキーに、デコードテーブルへの参照を格納。

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

コマンド実行の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | encode.rs | `crates/nu-command/src/strings/encode_decode/encode.rs` | `impl Command for Encode`（6-98行目） |
| 2-2 | decode.rs | `crates/nu-command/src/strings/encode_decode/decode.rs` | `impl Command for Decode`（34-104行目） |

**主要処理フロー**:
1. **encode.rs 76-86行目**: `run`メソッドでエンコーディング名取得とrun関数呼び出し
2. **decode.rs 84-93行目**: `run`メソッドでエンコーディング名取得とrun関数呼び出し

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

実際のエンコード/デコード処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | encode.rs | `crates/nu-command/src/strings/encode_decode/encode.rs` | run関数（100-140行目）- エンコード処理 |
| 3-2 | decode.rs | `crates/nu-command/src/strings/encode_decode/decode.rs` | run関数（106-153行目）- デコード処理 |
| 3-3 | decode.rs | `crates/nu-command/src/strings/encode_decode/decode.rs` | detect_and_decode関数（160-174行目）- OEM/encoding_rs分岐 |

**主要処理フロー**:
- **encode.rs 112-113行目**: encoding::encode呼び出し
- **decode.rs 165-166行目**: OEMコードページ判定
- **decode.rs 167行目**: encoding_rsによるデコード
- **decode.rs 169-172行目**: oem_cpによるデコード

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

```
Encode::run
    │
    ├─ call.req("encoding") - エンコーディング名取得
    ├─ call.has_flag("ignore-errors")
    │
    └─ run()
           │
           └─ encoding::encode()
                  │
                  └─ encoding_rs でエンコード

Decode::run
    │
    ├─ call.opt("encoding") - エンコーディング名取得（省略可）
    │
    └─ run()
           │
           └─ detect_and_decode()
                  │
                  ├─ 数値 → oem_cp でデコード
                  │      └─ decode_string_complete_table()
                  │
                  └─ 文字列 → encoding::decode()
                         └─ encoding_rs でデコード
```

### データフロー図

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

String ───▶ encode ───▶ encoding_rs ───▶ Binary
   │             │
   │             └─ "shift-jis" 等
   │
Binary ───▶ decode ───▶ detect_and_decode ───▶ String
   │             │              │
   │             │              ├─ OEM番号 → oem_cp
   │             │              │
   │             └─ encoding    └─ 文字列 → encoding_rs
   │                  名
   │
   └─ 0x[82 a0 82 a2] (Shift-JIS) → "あい"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| encode.rs | `crates/nu-command/src/strings/encode_decode/encode.rs` | ソース | encode コマンド実装 |
| decode.rs | `crates/nu-command/src/strings/encode_decode/decode.rs` | ソース | decode コマンド実装 |
| encoding.rs | `crates/nu-command/src/strings/encode_decode/encoding.rs` | ソース | 共通エンコーディング処理 |
| mod.rs | `crates/nu-command/src/strings/encode_decode/mod.rs` | ソース | モジュール定義 |
| encode_hex.rs | `crates/nu-cmd-extra/src/extra/strings/encode_decode/encode_hex.rs` | ソース | encode hex コマンド（extra） |
| decode_hex.rs | `crates/nu-cmd-extra/src/extra/strings/encode_decode/decode_hex.rs` | ソース | decode hex コマンド（extra） |
