# 機能設計書 44-YAML/TOML

## 概要

本ドキュメントは、NushellにおけるYAML/TOML形式のデータ変換機能（`from yaml`, `to yaml`, `from toml`, `to toml`コマンド）の詳細設計を記載する。これらのコマンドは、設定ファイル形式として広く使用されるYAMLおよびTOMLの読み書きを提供する。

### 本機能の処理概要

YAML/TOML変換機能は、人間が読み書きしやすい設定ファイル形式のデータ交換を提供する。Kubernetes、Docker Compose、CI/CDパイプライン（YAML）やRustプロジェクト、Hugo、多くのCLIツール（TOML）で使用されるこれらのフォーマットを効率的に処理できる。

**業務上の目的・背景**：YAMLはインフラストラクチャ as Code（IaC）の標準フォーマットとして広く採用されており、KubernetesマニフェストやAnsibleプレイブックなどで使用される。TOMLはRustエコシステム（Cargo.toml）やGitHub Actionsなどで使用される。これらの設定ファイルをシェルから効率的に読み書きできることは、DevOps作業において重要である。

**機能の利用シーン**：
- Kubernetesマニフェストの解析・編集
- Docker Compose設定の確認・変更
- CI/CDパイプライン設定の操作
- Cargo.tomlの依存関係確認・更新
- 設定ファイルの一括変換・マイグレーション

**主要な処理内容**：
1. `from yaml`: YAML文字列を構造化データに変換（マルチドキュメント対応）
2. `from yml`: from yamlのエイリアス
3. `to yaml`: 構造化データをYAML文字列に変換
4. `to yml`: to yamlのエイリアス
5. `from toml`: TOML文字列をレコードに変換（日時型対応）
6. `to toml`: レコードをTOML文字列に変換

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

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

## 関連画面

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

## 機能種別

データ変換 / フォーマット変換 / 設定ファイル処理

## 入力仕様

### 入力パラメータ

#### from yaml / from yml

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String | Yes | YAML文字列（パイプライン入力） | 有効なYAML形式 |

#### to yaml / to yml

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | Any | Yes | 変換対象データ（パイプライン入力） | - |
| --serialize / -s | Switch | No | シリアライズ不可型を文字列化 | - |

#### from toml

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String | Yes | TOML文字列（パイプライン入力） | 有効なTOML形式 |

#### to toml

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | record | Yes | 変換対象レコード（パイプライン入力） | トップレベルはレコードであること |
| --serialize / -s | Switch | No | シリアライズ不可型を文字列化 | - |

### 入力データソース

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

## 出力仕様

### 出力データ

#### from yaml / from yml

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Any | 変換後の構造化データ（単一/リスト） |

#### to yaml / to yml

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

#### from toml

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | record | 変換後のレコード |

#### to toml

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

### 出力先

標準出力（パイプライン出力）。content_typeメタデータを付与（application/yaml、text/x-toml）。

## 処理フロー

### 処理シーケンス

```
from yaml:
1. パイプライン入力を受け取る
   └─ String型を期待
2. YAMLデシリアライザで処理
   └─ マルチドキュメント対応
3. serde_yaml::Valueに変換
4. Nushell Valueに変換
   └─ convert_yaml_value_to_nu_value関数
5. ドキュメント数に応じて出力
   └─ 0: nothing, 1: 単一値, 2+: リスト

to yaml:
1. パイプライン入力を受け取る
   └─ Range展開
2. Nushell ValueをYAML Valueに変換
   └─ value_to_yaml_value関数
3. YAML文字列を生成
   └─ serde_yaml::to_string

from toml:
1. パイプライン入力を受け取る
   └─ 末尾に改行を追加
2. toml::from_strでパース
3. toml::ValueからNushell Valueに変換
   └─ convert_toml_to_value関数
4. 日時値の特別処理

to toml:
1. パイプライン入力を受け取る
   └─ recordのみ受け付け
2. Nushell ValueをTOML Valueに変換
   └─ value_to_toml_value関数
3. TOML文字列を生成
   └─ toml::to_string_pretty
```

### フローチャート

```mermaid
flowchart TD
    subgraph from_yaml ["from yaml"]
        A1[入力: String] --> B1[serde_yaml::Deserializer]
        B1 --> C1{ドキュメント数}
        C1 -->|0| D1[nothing]
        C1 -->|1| E1[単一Value]
        C1 -->|2+| F1[リスト]
    end

    subgraph to_yaml ["to yaml"]
        A2[入力: Any] --> B2[try_expand_range]
        B2 --> C2[value_to_yaml_value]
        C2 --> D2[serde_yaml::to_string]
        D2 --> E2[String + metadata]
    end

    subgraph from_toml ["from toml"]
        A3[入力: String] --> B3[末尾改行追加]
        B3 --> C3[toml::from_str]
        C3 --> D3[convert_toml_to_value]
        D3 --> E3{Datetime?}
        E3 -->|Yes| F3[chrono変換]
        E3 -->|No| G3[Value出力]
        F3 --> G3
    end

    subgraph to_toml ["to toml"]
        A4[入力: record] --> B4{recordかチェック}
        B4 -->|No| C4[エラー]
        B4 -->|Yes| D4[value_to_toml_value]
        D4 --> E4[toml::to_string_pretty]
        E4 --> F4[String + metadata]
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | マルチドキュメント | YAMLは複数ドキュメント（---区切り）をリストで返す | from yaml |
| BR-44-02 | 空ドキュメント | 空入力はnothingを返す | from yaml |
| BR-44-03 | 二重波括弧 | `{{ }}`形式のテンプレート記法を文字列として処理 | from yaml |
| BR-44-04 | タグ付き値 | YAMLタグ（!Tag）は文字列として保持 | from yaml |
| BR-44-05 | 日時変換 | TOML日時型はchrono日時型に変換 | from toml |
| BR-44-06 | トップレベル制約 | TOMLのトップレベルはテーブル（レコード）のみ | to toml |
| BR-44-07 | クロージャ処理 | --serializeでクロージャをソースコード文字列に変換 | to yaml/toml |
| BR-44-08 | content_type | YAMLはapplication/yaml、TOMLはtext/x-toml | to yaml/toml |

### 計算ロジック

**YAML型変換マッピング**:
- `null` → `nothing`
- `boolean` → `bool`
- `number (i64)` → `int`
- `number (f64)` → `float`
- `string` → `string`
- `sequence` → `list`
- `mapping` → `record`
- `tagged` → `string` (タグ+値)

**TOML型変換マッピング**:
- `boolean` → `bool`
- `integer` → `int`
- `float` → `float`
- `string` → `string`
- `datetime` → `date` (chronoで変換)
- `array` → `list`
- `table` → `record`

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnsupportedInput | パースエラー | YAMLが不正 | YAML形式を確認 |
| CantConvert | 変換エラー | TOMLへの変換に失敗 | データ形式を確認 |
| UnsupportedInput | トップレベルエラー | to tomlでrecord以外の入力 | recordを入力 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

- YAMLのマルチドキュメント処理時は全ドキュメントをメモリに保持
- IndexMapを使用してキー順序を保持

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

- YAMLはBillion Laughs攻撃に対して脆弱性があった（serde_yamlは対策済み）
- 信頼できないソースからのYAML/TOMLは悪意のあるデータを含む可能性がある

## 備考

- from yml / to ymlはそれぞれfrom yaml / to yamlのエイリアス
- YAMLのマッピング順序はIndexMapで保持される

---

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

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

### 推奨読解順序

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

YAML/TOMLの型変換関数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | yaml.rs (from) | `crates/nu-command/src/formats/from/yaml.rs` | convert_yaml_value_to_nu_value関数（74-185行目） |
| 1-2 | yaml.rs (to) | `crates/nu-command/src/formats/to/yaml.rs` | value_to_yaml_value関数（96-170行目） |
| 1-3 | toml.rs (from) | `crates/nu-command/src/formats/from/toml.rs` | convert_toml_to_value関数（108-130行目） |
| 1-4 | toml.rs (to) | `crates/nu-command/src/formats/to/toml.rs` | helper関数（52-111行目） |

**読解のコツ**: YAMLはserde_yaml::Valueを中間形式として使用。TOMLはtoml::Valueを使用。日時処理が複雑なので注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | yaml.rs | `crates/nu-command/src/formats/from/yaml.rs` | FromYaml構造体とfrom_yaml関数（233-242行目） |

**主要処理フロー**:
1. **187-206行目**: from_yaml_string_to_value関数
2. **190-198行目**: マルチドキュメント処理ループ
3. **201-205行目**: ドキュメント数に応じた出力形式決定

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | yaml.rs | `crates/nu-command/src/formats/to/yaml.rs` | ToYaml構造体とto_yaml関数（172-202行目） |

**主要処理フロー**:
- **43-44行目**: serializeフラグ取得とRange展開
- **185-186行目**: value_to_yaml_valueとserde_yaml::to_string
- **181-182行目**: application/yamlメタデータ設定

#### Step 4: TOML実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | toml.rs (from) | `crates/nu-command/src/formats/from/toml.rs` | FromToml構造体と日時変換（60-106行目） |
| 4-2 | toml.rs (to) | `crates/nu-command/src/formats/to/toml.rs` | ToToml構造体とto_toml_datetime（199-234行目） |

**読解のコツ**: TOMLの日時型（toml::value::Datetime）とchrono日時型の相互変換に注意。

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

```
from yaml
    │
    ├─ FromYaml::run
    │      └─ from_yaml
    │             └─ from_yaml_string_to_value
    │                    ├─ serde_yaml::Deserializer::from_str
    │                    └─ convert_yaml_value_to_nu_value (各ドキュメント)
    │
from yml (エイリアス) ─── 同上
    │
to yaml
    │
    ├─ ToYaml::run
    │      └─ to_yaml
    │             ├─ value_to_yaml_value
    │             └─ serde_yaml::to_string
    │
to yml (エイリアス) ─── 同上
    │
from toml
    │
    ├─ FromToml::run
    │      └─ convert_string_to_value
    │             ├─ toml::from_str
    │             └─ convert_toml_to_value
    │                    └─ convert_toml_datetime_to_value (日時処理)
    │
to toml
    │
    ├─ ToToml::run
    │      └─ to_toml
    │             ├─ value_to_toml_value
    │             │      └─ helper (再帰)
    │             └─ toml_into_pipeline_data
    │                    └─ toml::to_string_pretty
```

### データフロー図

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

from yaml:
String ───▶ serde_yaml::Value ───▶ convert_yaml_value_to_nu_value ───▶ Value

to yaml:
Value ───▶ value_to_yaml_value ───▶ serde_yaml::Value ───▶ String
                                         │
                                         └── content_type: application/yaml

from toml:
String ───▶ toml::Value ───▶ convert_toml_to_value ───▶ record

to toml:
record ───▶ value_to_toml_value ───▶ toml::Value ───▶ String
                                         │
                                         └── content_type: text/x-toml
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| yaml.rs (from) | `crates/nu-command/src/formats/from/yaml.rs` | ソース | from yaml/ymlコマンド実装 |
| yaml.rs (to) | `crates/nu-command/src/formats/to/yaml.rs` | ソース | to yaml/ymlコマンド実装 |
| toml.rs (from) | `crates/nu-command/src/formats/from/toml.rs` | ソース | from tomlコマンド実装 |
| toml.rs (to) | `crates/nu-command/src/formats/to/toml.rs` | ソース | to tomlコマンド実装 |
