# 機能設計書 94-Formatsプラグイン

## 概要

本ドキュメントはNushellのFormatsプラグイン（nu_plugin_formats）について記述する。追加フォーマット（INI、plist、ICS、EML、VCF）の読み書き機能を提供するプラグインの設計を定義する。

### 本機能の処理概要

Formatsプラグインは、Nushellのコアでサポートされていない追加的なファイルフォーマットの読み込み・書き出し機能を提供する。設定ファイル（INI、plist）、カレンダーデータ（ICS）、メール（EML）、連絡先（VCF）といった様々なフォーマットを扱う。

**業務上の目的・背景**：システム設定ファイル（INI、plist）やカレンダー・連絡先データ（ICS、VCF）など、特定のユースケースで必要となるフォーマットをサポートすることで、Nushellの適用範囲を広げる。特にmacOSのplistやWindowsのINIファイルなど、OS固有の設定ファイルを扱う際に有用。

**機能の利用シーン**：
- アプリケーション設定ファイル（INI形式）の読み込み・編集
- macOSのplistファイルの読み込み・書き込み
- カレンダーイベント（ICS形式）のパース
- メールファイル（EML形式）の解析
- 連絡先データ（VCF形式）の読み込み

**主要な処理内容**：
1. INI: セクション/キー/値形式のパースとレコード変換
2. plist: Apple Property List形式の読み込み・書き込み
3. ICS: iCalendar形式のイベントデータ抽出
4. EML: 電子メールのヘッダー・本文解析
5. VCF: vCard形式の連絡先情報抽出

**関連システム・外部連携**：iniクレート、plistクレート、ical/vobject関連クレート

**権限による制御**：特になし。入力データの変換処理のみ。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLIコマンドとして提供され、特定の画面とは関連しない |

## 機能種別

フォーマット変換 / パース処理 / シリアライズ処理

## 入力仕様

### 入力パラメータ

#### from ini

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String (pipeline) | Yes | INI形式の文字列 | 有効なINI形式 |
| --no-quote | Switch | No | クォート処理を無効化 | - |
| --no-escape | Switch | No | エスケープシーケンス処理を無効化 | - |
| --indented-multiline-value | Switch | No | インデントされた複数行値を許可 | - |
| --preserve-key-leading-whitespace | Switch | No | キーの先頭空白を保持 | - |

#### from plist

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String/Binary (pipeline) | Yes | plist形式のデータ | 有効なplist形式 |

#### from ics

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String (pipeline) | Yes | ICS形式の文字列 | 有効なiCalendar形式 |

#### from eml

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String (pipeline) | Yes | EML形式の文字列 | 有効なメール形式 |

#### from vcf

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String (pipeline) | Yes | VCF形式の文字列 | 有効なvCard形式 |

#### to plist

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | Any (pipeline) | Yes | 変換元のNushell値 | 変換可能な型 |

### 入力データソース

- パイプライン入力: 各フォーマットの文字列またはバイナリデータ
- ファイルから読み込み: `open --raw file.ini | from ini`

## 出力仕様

### 出力データ

#### from ini

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Record | セクション名をキー、キー/値ペアをネストしたレコード |

#### from plist

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Any | plistの内容に応じた型（Record, List, String, Int, Float, Bool, Binary, Date） |

#### from ics

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Table | イベントのリスト |

#### from eml

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Subject | String | 件名 |
| From | String | 送信者 |
| To | String | 受信者 |
| Date | String | 日時 |
| Body | String | 本文 |
| ... | ... | その他のヘッダー |

#### from vcf

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Table | 連絡先情報のリスト |

#### to plist

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

### 出力先

- パイプライン出力

## 処理フロー

### 処理シーケンス

```
from ini:
1. 入力文字列を取得
2. ParseOptionを設定
   └─ フラグに応じてオプションを変更
3. ini::Ini::load_from_str_optでパース
4. セクションごとにレコードを構築
   └─ セクション名がNoneの場合は空文字列キー
5. ネストしたレコードとして返却

from plist:
1. 入力を文字列またはバイナリとして取得
2. plist::from_bytesでパース
3. convert_plist_valueで型変換
   └─ 再帰的にNushell値に変換
4. 変換結果を返却

to plist:
1. 入力Nushell値を取得
2. convert_nu_value_to_plistでplist値に変換
3. plist::to_string_xmlでXML出力
4. 文字列として返却
```

### フローチャート

```mermaid
flowchart TD
    A[from ini] --> B[入力文字列取得]
    B --> C[ParseOption設定]
    C --> D[ini::Ini::load_from_str_opt]
    D --> E{パース成功?}
    E -->|No| F[エラー返却]
    E -->|Yes| G[セクションごとにRecord構築]
    G --> H[ネストしたRecord返却]

    I[from plist] --> J[入力データ取得]
    J --> K[plist::from_bytes]
    K --> L{パース成功?}
    L -->|No| M[エラー返却]
    L -->|Yes| N[convert_plist_value]
    N --> O[Nushell値返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-94-01 | INIセクションなし | セクションなしのキー/値は空文字列キーに格納 | from ini |
| BR-94-02 | plistバイナリ対応 | バイナリplist形式も読み込み可能 | from plist |
| BR-94-03 | plist日付変換 | plist DateはNushell datetimeに変換 | from plist |
| BR-94-04 | plist UID | plist UIDはfloatに変換 | from plist |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnsupportedInput | ShellError | INIのパース失敗 | 有効なINI形式を入力 |
| Could not load plist | LabeledError | plistのパース失敗 | 有効なplist形式を入力 |
| Invalid input | LabeledError | 不正な入力型 | 文字列またはバイナリを入力 |

### リトライ仕様

特になし。

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

該当なし（読み取り/変換処理のみ）。

## パフォーマンス要件

- 即座に処理実行
- 大規模ファイルの場合はメモリ使用量に注意

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

- 外部ファイルのパース処理のため、不正なデータに注意
- plistバイナリ形式は信頼できるソースからのみ読み込むこと

## 備考

- INIファイルのセクション名のない値はプロパティとして扱われる
- plistはXMLとバイナリの両形式をサポート
- to plistはXML形式でのみ出力

---

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

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

### 推奨読解順序

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

プラグインの構造とコマンド登録を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lib.rs | `crates/nu_plugin_formats/src/lib.rs` | FormatCmdsPluginの定義とコマンド登録 |

**読解のコツ**: FormatCmdsPluginがPluginトレイトを実装し、各フォーマットコマンドを登録している構造を確認。

#### Step 2: INIフォーマットを理解する

INIファイルのパース処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ini.rs | `crates/nu_plugin_formats/src/from/ini.rs` | FromIniコマンドの実装 |

**主要処理フロー（ini.rs）**:
1. **47-116行目**: runメソッド - メイン処理
2. **57-73行目**: ParseOptionの設定
3. **75-76行目**: ini::Ini::load_from_str_optでパース
4. **78-106行目**: セクションごとのレコード構築
5. **119-175行目**: 使用例

#### Step 3: plistフォーマットを理解する

Apple plistのパース・出力処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | from/plist.rs | `crates/nu_plugin_formats/src/from/plist.rs` | FromPlistコマンドの実装 |
| 3-2 | to/plist.rs | `crates/nu_plugin_formats/src/to/plist.rs` | IntoPlistコマンドの実装 |

**主要処理フロー（from/plist.rs）**:
1. **44-69行目**: runメソッド - 入力タイプに応じた処理分岐
2. **76-94行目**: convert_plist_value - plist値からNushell値への変換
3. **96-106行目**: convert_dict - Dictionaryの変換
4. **108-113行目**: convert_array - 配列の変換
5. **115-122行目**: convert_date - 日付の変換

#### Step 4: その他のフォーマットを理解する

ICS、EML、VCFの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ics.rs | `crates/nu_plugin_formats/src/from/ics.rs` | iCalendarパース |
| 4-2 | eml.rs | `crates/nu_plugin_formats/src/from/eml.rs` | メールパース |
| 4-3 | vcf.rs | `crates/nu_plugin_formats/src/from/vcf.rs` | vCardパース |

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

```
FormatCmdsPlugin
    │
    ├─ FromIni
    │      └─ run()
    │             ├─ ParseOption設定
    │             └─ ini::Ini::load_from_str_opt()
    │
    ├─ FromPlist
    │      └─ run()
    │             ├─ plist::from_bytes()
    │             └─ convert_plist_value()
    │                    ├─ convert_dict()
    │                    ├─ convert_array()
    │                    └─ convert_date()
    │
    ├─ IntoPlist
    │      └─ run()
    │             ├─ convert_nu_value_to_plist()
    │             └─ plist::to_string_xml()
    │
    ├─ FromIcs
    │      └─ run()
    │             └─ ical::parser
    │
    ├─ FromEml
    │      └─ run()
    │             └─ mailparse
    │
    └─ FromVcf
           └─ run()
                  └─ vobject::parse_component
```

### データフロー図

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

INI文字列   ─────────▶   ini::Ini            ─────▶   Record
                          └─ load_from_str_opt         {section: {key: val}}

plistデータ ─────────▶   plist::from_bytes   ─────▶   Any
(XML/Binary)              └─ convert_plist_value       (Record/List/etc)

Nushell値   ─────────▶   plist::to_string_xml ─────▶  plist XML文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lib.rs | `crates/nu_plugin_formats/src/lib.rs` | ソース | プラグイン定義・コマンド登録 |
| from/mod.rs | `crates/nu_plugin_formats/src/from/mod.rs` | ソース | fromモジュール |
| from/ini.rs | `crates/nu_plugin_formats/src/from/ini.rs` | ソース | from ini実装 |
| from/plist.rs | `crates/nu_plugin_formats/src/from/plist.rs` | ソース | from plist実装 |
| from/ics.rs | `crates/nu_plugin_formats/src/from/ics.rs` | ソース | from ics実装 |
| from/eml.rs | `crates/nu_plugin_formats/src/from/eml.rs` | ソース | from eml実装 |
| from/vcf.rs | `crates/nu_plugin_formats/src/from/vcf.rs` | ソース | from vcf実装 |
| to/mod.rs | `crates/nu_plugin_formats/src/to/mod.rs` | ソース | toモジュール |
| to/plist.rs | `crates/nu_plugin_formats/src/to/plist.rs` | ソース | to plist実装 |
| main.rs | `crates/nu_plugin_formats/src/main.rs` | ソース | プラグインエントリーポイント |
