# 機能設計書 105-TOML

## 概要

本ドキュメントは、Julia標準ライブラリ `TOML` モジュールが提供するTOMLファイルの解析・生成機能の設計を記述する。TOML v1.0仕様に準拠し、TOMLテキストからJulia辞書（Dict）への変換（parse）、およびJulia辞書からTOMLテキストへの変換（print）を提供する。

### 本機能の処理概要

**業務上の目的・背景**：JuliaのパッケージシステムはTOMLファイル（`Project.toml`, `Manifest.toml`）を設定ファイルとして使用しており、その解析・生成はJuliaエコシステムの根幹をなす。また、一般的なアプリケーション設定ファイルのフォーマットとしてもTOMLは広く利用されている。

**機能の利用シーン**：`Project.toml`/`Manifest.toml` の読み書き、アプリケーション設定ファイルの管理、設定データの永続化。

**主要な処理内容**：
1. TOMLテキストの解析（`parse`/`tryparse`/`parsefile`/`tryparsefile`）
2. TOML形式でのデータ出力（`print`）
3. `Parser` オブジェクトの再利用による高効率パース
4. Dates統合（DateTime, Date, Time型のサポート）
5. インラインテーブルサポート（`inline_tables` キーワード引数）

**関連システム・外部連携**：Base.TOML（コアパーサー実装）、Dates（日時型サポート）。

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

## 関連画面

本機能に直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | パッケージシステムや設定管理のバックエンド処理として利用 |

## 機能種別

データ変換 / ファイルI/O

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | AbstractString / IO | Yes（parse時） | TOML文字列またはストリーム | TOML v1.0仕様に準拠 |
| f | AbstractString | Yes（parsefile時） | TOMLファイルパス | ファイルが存在すること |
| p | Parser | No | 再利用可能なパーサーオブジェクト | - |
| data | AbstractDict | Yes（print時） | TOML出力対象のデータ | サポートされた型のみ |
| sorted | Bool | No | キーのソート有無（デフォルトfalse） | - |
| by | Function | No | ソート関数（デフォルトidentity） | - |
| inline_tables | IdSet | No | インラインテーブルとして出力する辞書のセット | Julia 1.11以降 |

### 入力データソース

TOMLファイル、文字列リテラル、IOストリーム。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| parsed_table | Dict{String, Any} | parse結果の辞書 |
| toml_text | String | print結果のTOML文字列 |
| parser_error | ParserError | tryparse失敗時のエラー情報 |

### 出力先

- parse: 戻り値として Dict を返す
- print: IOストリーム（デフォルトstdout）

## 処理フロー

### 処理シーケンス

```
1. parse(str) / parsefile(f)
   ├─ Parser{Dates}() でパーサー生成
   ├─ Internals.parse() でTOMLテキストを解析
   └─ Dict{String, Any} を返却
2. print(io, data)
   ├─ Internals.Printer.print() でDict→TOML変換
   └─ IOに書き込み
```

### フローチャート

```mermaid
flowchart TD
    A["TOML.parse(str) / TOML.parsefile(f)"] --> B{"入力ソース"}
    B -->|文字列| C["Internals.Parser{Dates}(str)"]
    B -->|ファイル| D["_readstring(f) -> Internals.Parser{Dates}(str)"]
    C --> E["Internals.parse(parser)"]
    D --> E
    E --> F{"成功?"}
    F -->|成功| G["Dict{String, Any} を返却"]
    F -->|失敗| H{"parse or tryparse?"}
    H -->|parse| I["ParserError を throw"]
    H -->|tryparse| J["ParserError を return"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-105-1 | TOML v1.0準拠 | TOML v1.0仕様に完全準拠したパースを行う | 全parse操作 |
| BR-105-2 | Dates統合 | DateTime, Date, Time型はTOMLのdatetime-local/date/time型として扱う | parse/print時 |
| BR-105-3 | parseとtryparseの分離 | parseは失敗時にthrow、tryparseは失敗時にParserErrorをreturn | parse/tryparse呼び出し時 |
| BR-105-4 | print対応型 | AbstractDict, AbstractVector, AbstractString, Integer, AbstractFloat, Bool, DateTime, Date, Timeをサポート | print時 |
| BR-105-5 | Parser再利用 | 同一Parserオブジェクトの再利用で内部構造体の再割り当てを回避 | 大量のファイル解析時 |

### 計算ロジック

特になし。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ParserError | TOML構文エラー | TOMLテキストを修正 |
| - | ErrorException | ファイルが存在しない | 正しいファイルパスを指定 |
| - | MethodError | printで未サポート型を出力 | to_toml変換関数を提供 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- Parser再利用で内部バッファの再割り当てを回避し、大量ファイル解析時に有効
- コアパーサーはBase.TOMLに実装されており、システムイメージに含まれる

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

- TOMLパーサーは任意コード実行の機能を持たない
- ファイルパスの検証は `isfile` チェックのみ

## 備考

- `to_toml` コールバック関数でカスタム型のTOML出力を拡張可能
- Base.TOMLCache と連携し、パッケージシステムでのキャッシュ付きTOML読み込みを実現

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `Parser` 構造体（39-41行目）: 内部のInternals.Parser{Dates}をラップ |
| 1-2 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `ParserError` 定数（120行目）: Internals.ParserErrorのエイリアス |

**読解のコツ**: TOMLモジュールはBase.TOMLのコアパーサーをDates型対応でラップするファサードモジュール。コアのパース処理はBase.TOMLモジュールにある。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `parsefile(f)`（57-60行目）: ファイル読み込み+パース |
| 2-2 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `parse(str)`（86-91行目）: 文字列/IOパース |
| 2-3 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `tryparse(str)`（103-108行目）: エラーをreturnするパース |
| 2-4 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `print` 定数（139行目）: Internals.Printer.printのエイリアス |

#### Step 3: 内部モジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TOML.jl | `stdlib/TOML/src/TOML.jl` | `Internals` モジュール（12-25行目）: Base.TOMLからのインポートとPrinterサブモジュール |
| 3-2 | print.jl | `stdlib/TOML/src/print.jl` | TOML出力（print）の実装 |

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

```
TOML.parse(str) / TOML.parsefile(f)
    │
    ├─ _readstring(f)                    -- ファイル読み込み（parsefileのみ）
    │
    ├─ Internals.Parser{Dates}(str)      -- パーサー生成
    │      └─ Base.TOML.Parser           -- コアパーサー
    │
    └─ Internals.parse(parser)           -- パース実行
           └─ Base.TOML.parse()          -- コア解析

TOML.print(io, data)
    └─ Internals.Printer.print(io, data)
           └─ 型別出力（Dict/Array/String/Number/Bool/DateTime等）
```

### データフロー図

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

TOMLファイル ─────▶ _readstring() ──▶ 文字列
       または
TOML文字列 ─────▶ Parser{Dates}() ──▶ パーサーオブジェクト
                     │
                     ▼
               Internals.parse() ──▶ Dict{String, Any}

Dict{String, Any} ──▶ Internals.Printer.print() ──▶ TOML文字列 ──▶ IO
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TOML.jl | `stdlib/TOML/src/TOML.jl` | ソース | TOMLモジュールのファサード |
| print.jl | `stdlib/TOML/src/print.jl` | ソース | TOML出力（Printer）実装 |
| precompile.jl | `stdlib/TOML/src/precompile.jl` | ソース | 事前コンパイルワークロード |
| Base.TOML | `base/toml_parser.jl` | ソース | コアTOMLパーサー（Baseモジュール内） |
