# 機能設計書 42-JSON

## 概要

本ドキュメントは、NushellにおけるJSON形式のデータ変換機能（`from json`および`to json`コマンド）の詳細設計を記載する。これらのコマンドは、JSON文字列と構造化データ間の相互変換を提供する。

### 本機能の処理概要

JSON変換機能は、現代のデータ交換において最も重要なフォーマットの一つであるJSONの読み書きを提供する。Web API、設定ファイル、データ保存など、様々な場面でJSONが使用されており、これらのデータをNushellのテーブル形式で操作可能にする。

**業務上の目的・背景**：JSONはREST APIの標準レスポンス形式であり、多くのCLIツールや設定ファイルでも採用されている。シェル環境でJSONデータを効率的に処理できることは、DevOps作業、データ分析、自動化スクリプトの作成において不可欠である。

**機能の利用シーン**：
- Web APIのレスポンスを解析してデータを抽出する
- JSONログファイルを構造化データとして分析する
- 設定ファイル（package.json等）を読み込んで値を取得・更新する
- Nushellで作成したデータをJSON形式でエクスポートする
- 行区切りJSON（NDJSON/JSONLines）のストリーム処理

**主要な処理内容**：
1. `from json`: JSON文字列をNushellの構造化データ（レコード/リスト）に変換
2. `from json --objects`: 行区切りJSONをストリームとして処理
3. `from json --strict`: JSON仕様に厳密に準拠した解析
4. `to json`: Nushellデータをjson文字列に変換
5. `to json --raw`: 空白なしのコンパクト出力
6. `to json --indent`: カスタムインデント幅
7. `to json --tabs`: タブでインデント

**関連システム・外部連携**：nu_jsonクレートおよびserde_jsonクレートを使用してJSONのパース・シリアライズを行う。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLI専用機能のため画面なし |

## 機能種別

データ変換 / フォーマット変換

## 入力仕様

### 入力パラメータ

#### from json

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String | Yes | JSON文字列（パイプライン入力） | 有効なJSON形式 |
| --objects / -o | Switch | No | 行区切りJSONモード | - |
| --strict / -s | Switch | No | 厳密なJSON解析モード | - |

#### to json

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | Any | Yes | 変換対象データ（パイプライン入力） | - |
| --raw / -r | Switch | No | 空白なしコンパクト出力 | - |
| --indent / -i | Number | No | インデント幅（スペース数） | 正の整数 |
| --tabs / -t | Number | No | インデントタブ数 | 正の整数 |
| --serialize / -s | Switch | No | シリアライズ不可型を文字列化 | - |

### 入力データソース

パイプライン入力（from json: String型、to json: Any型）

## 出力仕様

### 出力データ

#### from json

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Any | 変換後の構造化データ（record/list/値） |

#### to json

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | String | JSON形式の文字列 |

### 出力先

標準出力（パイプライン出力）。to jsonはcontent_type: "application/json"メタデータを付与。

## 処理フロー

### 処理シーケンス

```
from json:
1. パイプライン入力を受け取る
   └─ String型またはByteStream型を期待
2. フラグを解析
   └─ objects, strictフラグを取得
3. --objectsの場合は行単位でパース
   └─ ListStreamを返す
4. 単一JSONの場合
   └─ 文字列全体をパース
5. JSON値をNushell値に変換
   └─ convert_nujson_to_value関数

to json:
1. パイプライン入力を受け取る
   └─ 任意の型を受け付ける
2. フラグを解析
   └─ raw, indent, tabs, serializeを取得
3. Rangeを展開
   └─ try_expand_range
4. Nushell値をJSON値に変換
   └─ value_to_json_value関数
5. JSON文字列を生成
   └─ nu_json::to_string系関数
```

### フローチャート

```mermaid
flowchart TD
    subgraph from_json ["from json"]
        A1[入力: String] --> B1{--objects?}
        B1 -->|Yes| C1[行単位ストリーム処理]
        B1 -->|No| D1[文字列全体をパース]
        C1 --> E1{--strict?}
        D1 --> E1
        E1 -->|Yes| F1[serde_json使用]
        E1 -->|No| G1[nu_json使用]
        F1 --> H1[convert_nujson_to_value]
        G1 --> H1
        H1 --> I1[Nushell Value出力]
    end

    subgraph to_json ["to json"]
        A2[入力: Any] --> B2[value_to_json_value]
        B2 --> C2{--raw?}
        C2 -->|Yes| D2[to_string_raw]
        C2 -->|No| E2{--tabs?}
        E2 -->|Yes| F2[to_string_with_tab_indentation]
        E2 -->|No| G2{--indent?}
        G2 -->|Yes| H2[to_string_with_indent]
        G2 -->|No| I2[to_string]
        D2 --> J2[String出力 + metadata]
        F2 --> J2
        H2 --> J2
        I2 --> J2
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | 空文字列処理 | 空文字列入力は`nothing`を返す | from json実行時 |
| BR-42-02 | コメント許容 | nu_jsonではコメントを許容する | --strict未指定時 |
| BR-42-03 | 末尾カンマ許容 | nu_jsonでは末尾カンマを許容する | --strict未指定時 |
| BR-42-04 | u64変換 | i64の範囲を超えるu64はエラー | from json実行時 |
| BR-42-05 | クロージャ | クロージャはデフォルトでエラー | to json実行時、--serialize未指定時 |
| BR-42-06 | Range展開 | RangeはArrayに展開される | to json実行時 |
| BR-42-07 | メタデータ | content_typeが"application/json"に設定される | to json実行時 |

### 計算ロジック

**型変換マッピング (JSON → Nushell)**:
- `null` → `nothing`
- `boolean` → `bool`
- `number (integer)` → `int`
- `number (float)` → `float`
- `string` → `string`
- `array` → `list`
- `object` → `record`

**型変換マッピング (Nushell → JSON)**:
- `bool` → `boolean`
- `int` → `number`
- `float` → `number`
- `string` → `string`
- `list` → `array`
- `record` → `object`
- `date` → `string` (ISO8601形式)
- `filesize` → `number`
- `duration` → `number`
- `binary` → `array` (バイト配列)
- `nothing` → `null`

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| GenericError | パースエラー | JSON構文が不正 | JSON形式を確認 |
| CantConvert | 変換エラー | JSONから構造化データへ変換できない | データ形式を確認 |
| UnsupportedInput | 入力エラー | クロージャ等の非対応型 | --serializeを使用 |
| OnlySupportsThisInputType | 型エラー | String/ByteStream以外の入力 | 正しい型を入力 |

### リトライ仕様

リトライは不要。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- 大きなJSONファイルの処理時はメモリ使用量に注意
- --objectsモードでストリーム処理することでメモリ効率を向上可能

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

- 信頼できないソースからのJSONは悪意のあるデータを含む可能性がある
- 非常に深いネストのJSONはスタックオーバーフローの原因となる可能性がある

## 備考

- nu_jsonはJSON5ライクな拡張構文をサポート
- --strictを指定するとRFC準拠の厳密なパースを行う

---

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

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

### 推奨読解順序

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

JSONとNushell値の変換関数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | json.rs (from) | `crates/nu-command/src/formats/from/json.rs` | convert_nujson_to_value関数（155-191行目）の型マッピング |
| 1-2 | json.rs (to) | `crates/nu-command/src/formats/to/json.rs` | value_to_json_value関数（114-177行目）の型マッピング |

**読解のコツ**: nu_json::Valueの各バリアント（Array, Bool, F64, I64, Null, Object, U64, String）がどのようにNushell Valueに変換されるかを追う。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | json.rs | `crates/nu-command/src/formats/from/json.rs` | FromJson構造体とrun関数（67-129行目） |

**主要処理フロー**:
1. **76行目**: strictフラグの取得
2. **80行目**: objectsフラグの判定
3. **82-112行目**: objectsモードの処理（read_json_lines関数呼び出し）
4. **113-128行目**: 単一値モードの処理

#### Step 3: to jsonのエントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | json.rs | `crates/nu-command/src/formats/to/json.rs` | ToJson構造体とrun関数（44-89行目） |

**主要処理フロー**:
- **51-54行目**: フラグ取得（raw, tabs, indent, serialize）
- **58行目**: Range展開
- **60行目**: value_to_json_value呼び出し
- **62-70行目**: 出力形式の選択

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

```
from json
    │
    ├─ FromJson::run
    │      ├─ (--objects) read_json_lines
    │      │      └─ convert_string_to_value / convert_string_to_value_strict
    │      │             └─ convert_nujson_to_value
    │      │
    │      └─ (単一) collect_string_strict
    │             └─ convert_string_to_value / convert_string_to_value_strict
    │                    └─ convert_nujson_to_value
    │
to json
    │
    ├─ ToJson::run
    │      ├─ try_expand_range
    │      ├─ input.into_value
    │      ├─ value_to_json_value
    │      │      └─ json_list (再帰)
    │      │
    │      └─ nu_json::to_string系
```

### データフロー図

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

from json:
String ───▶ nu_json::from_str ───▶ nu_json::Value ───▶ Value
              serde_json::from_str

to json:
Value ───▶ value_to_json_value ───▶ nu_json::Value ───▶ String
                                         │
                                         └── content_type: application/json
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| json.rs (from) | `crates/nu-command/src/formats/from/json.rs` | ソース | from jsonコマンド実装 |
| json.rs (to) | `crates/nu-command/src/formats/to/json.rs` | ソース | to jsonコマンド実装 |
| mod.rs | `crates/nu-command/src/formats/from/mod.rs` | ソース | fromコマンド群のモジュール定義 |
| mod.rs | `crates/nu-command/src/formats/to/mod.rs` | ソース | toコマンド群のモジュール定義 |
