# 機能設計書 76-メタデータ

## 概要

本ドキュメントは、Nushellのメタデータ機能の設計仕様を定義する。metadata、metadata setコマンドは、パイプラインデータに付随するメタ情報の取得・設定を行う機能を提供する。

### 本機能の処理概要

メタデータ機能は、Nushellのパイプラインデータに紐づくメタ情報（データソース、コンテンツタイプ、パス情報など）を取得・設定する機能群である。値のスパン情報、ファイルパス、カスタムメタデータなどを操作できる。

**業務上の目的・背景**：Nushellでは、データがどこから来たか（ファイル、コマンド出力など）の情報を保持し、後続の処理で活用できる。例えば、テーブルのカラムがパスであることをメタデータで示すことで、ファイルブラウザのような表示が可能になる。

**機能の利用シーン**：
- データのソース（ファイルパス等）を確認したい場合
- データのコンテンツタイプを設定・取得したい場合
- カスタムメタデータを付加してパイプラインで伝播させたい場合
- 値のスパン（ソースコード上の位置）を確認したい場合

**主要な処理内容**：
1. `metadata`：パイプライン入力または変数のメタデータを取得
2. `metadata set`：パイプラインデータにメタデータを設定

**関連システム・外部連携**：
- nu-protocol::PipelineMetadata：メタデータ構造体
- nu-protocol::DataSource：データソース列挙型

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

## 関連画面

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

## 機能種別

デバッグ・メタ情報操作機能

## 入力仕様

### 入力パラメータ

#### metadata

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| expression | Any | No | メタデータを取得する式 | - |

#### metadata set

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| closure | Closure | No | メタデータを変換するクロージャ | フラグと排他 |
| --datasource-filepath (-f) | Filepath | No | FilePath型のDataSourceを設定 | - |
| --datasource-ls (-l) | switch | No | (非推奨) Ls型のDataSourceを設定 | - |
| --path-columns (-p) | List<String> | No | パスメタデータを設定するカラムのリスト | - |
| --content-type (-c) | String | No | コンテンツタイプを設定 | - |
| --merge (-m) | Record | No | (非推奨) カスタムメタデータをマージ | - |

### 入力データソース

- パイプライン入力（metadataコマンド）
- 変数参照式（metadataコマンドの引数）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| metadata出力 | Record | メタデータ情報（span, source, content_type等） |
| metadata set出力 | Any | メタデータ付きの入力データ |

### 出力先

標準出力（パイプライン出力）

## 処理フロー

### 処理シーケンス

```
1. metadata コマンド
   └─ 引数の有無を確認
   └─ 引数あり: 変数/式のスパン情報とメタデータを取得
   └─ 引数なし: パイプライン入力のメタデータを取得
   └─ レコード形式で返却

2. metadata set コマンド
   └─ 現在のメタデータを取得
   └─ クロージャ指定時: クロージャでメタデータを変換
   └─ フラグ指定時: 各フラグに応じてメタデータを更新
   └─ 更新されたメタデータを入力に設定して返却
```

### フローチャート

```mermaid
flowchart TD
    A[メタデータコマンド] --> B{サブコマンド?}

    B -->|metadata| C{引数あり?}
    C -->|Yes| D[式を評価]
    D --> E{FullCellPath?}
    E -->|Yes| F[変数のスパン情報取得]
    E -->|No| G[値のメタデータ取得]
    C -->|No| H[パイプライン入力のメタデータ取得]
    F --> I[レコード構築]
    G --> I
    H --> I

    B -->|metadata set| J{クロージャ指定?}
    J -->|Yes| K[現在のメタデータをレコード化]
    K --> L[クロージャ実行]
    L --> M[結果レコードからメタデータ復元]
    J -->|No| N[フラグを処理]
    N --> O{各フラグ}
    O -->|--content-type| P[content_type設定]
    O -->|--datasource-filepath| Q[DataSource::FilePath設定]
    O -->|--path-columns| R[path_columns設定]
    M --> S[メタデータを入力に設定]
    P --> S
    Q --> S
    R --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-1 | span情報 | 変数のスパン情報をレコードに含める | metadata引数指定時 |
| BR-76-2 | source情報 | DataSourceを文字列として出力 | DataSourceがNone以外 |
| BR-76-3 | クロージャ排他 | クロージャとフラグは同時に使用不可 | metadata set実行時 |
| BR-76-4 | 非推奨フラグ | --datasource-lsと--mergeは非推奨 | 該当フラグ使用時 |

### 計算ロジック

特になし

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

該当なし（本機能はデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IncompatibleParameters | パイプライン入力と引数の両方が指定された | どちらか一方のみを指定 |
| - | GenericError | クロージャとフラグが同時に指定された | クロージャまたはフラグのみを使用 |
| - | GenericError | クロージャがレコードを返さなかった | レコードを返すクロージャを指定 |
| - | PipelineEmpty | metadata setに空パイプラインが渡された | 有効なデータを渡す |
| - | IncompatibleParameters | --datasource-filepathと--datasource-lsが両方指定 | どちらか一方のみを指定 |

### リトライ仕様

リトライは行わない。

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

該当なし

## パフォーマンス要件

特になし

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

- メタデータにはファイルパス情報が含まれる可能性がある
- カスタムメタデータに機密情報を格納しないよう注意が必要

## 備考

- metadata setのクロージャは現在のメタデータをレコードとして受け取り、新しいレコードを返す
- path_columnsメタデータはテーブルのカラムがパスであることを示し、ファイルブラウザ風の表示に活用される
- content_typeはHTTPレスポンスなどのMIMEタイプ情報を保持する

---

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

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

### 推奨読解順序

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

PipelineMetadataとDataSourceの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | util.rs | `crates/nu-command/src/debug/util.rs` | extend_record_with_metadata、parse_metadata_from_record |

**読解のコツ**: PipelineMetadataはdata_source、path_columns、content_type、customの4フィールドを持ち、これらがレコードとして表現される。

#### Step 2: 各コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | metadata.rs | `crates/nu-command/src/debug/metadata.rs` | metadataコマンド - 引数の種類による分岐 |
| 2-2 | metadata_set.rs | `crates/nu-command/src/debug/metadata_set.rs` | metadata setコマンド - クロージャとフラグの処理 |
| 2-3 | util.rs | `crates/nu-command/src/debug/util.rs` | 共通ユーティリティ関数 |

**主要処理フロー** (metadata.rs):
- **32-34行目**: requires_ast_for_arguments() - AST情報が必要
- **46-55行目**: パイプライン入力と引数の排他チェック
- **57-103行目**: 引数の種類に応じた分岐処理
- **122-130行目**: build_metadata_record_value関数 - スパンとメタデータをレコード化

**主要処理フロー** (metadata_set.rs):
- **58-81行目**: 非推奨フラグの定義
- **99-104行目**: 現在のメタデータの取得
- **106-140行目**: クロージャ処理（フラグと排他）
- **142-180行目**: フラグベースのメタデータ更新

**主要処理フロー** (util.rs):
- **4-44行目**: extend_record_with_metadata - メタデータをレコードに追加
- **46-91行目**: parse_metadata_from_record - レコードからメタデータを復元
- **93-99行目**: build_metadata_record - パイプラインのメタデータをレコード化

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

```
Metadata::run (metadata.rs)
    ├─ 引数あり:
    │      ├─ FullCellPath (変数参照)
    │      │      └─ stack.get_var_with_origin()
    │      │             └─ build_metadata_record_value()
    │      │
    │      └─ その他
    │             └─ call.req()
    │                    └─ build_metadata_record_value()
    │
    └─ 引数なし:
           └─ build_metadata_record()
                  └─ extend_record_with_metadata()

MetadataSet::run (metadata_set.rs)
    ├─ クロージャ処理:
    │      ├─ extend_record_with_metadata()
    │      ├─ ClosureEvalOnce::run_with_value()
    │      └─ parse_metadata_from_record()
    │
    └─ フラグ処理:
           ├─ content_type設定
           ├─ path_columns設定
           ├─ DataSource設定
           └─ custom merge
```

### データフロー図

```
[metadata]
PipelineData/変数 ───▶ メタデータ抽出 ───▶ Record
                            │
                            ├─ span: {start, end}
                            ├─ source: ファイルパス等
                            ├─ path_columns: [カラム名...]
                            └─ content_type: MIMEタイプ

[metadata set]
PipelineData ───▶ メタデータ取得 ───▶ 更新 ───▶ PipelineData
                       │                │
                       │                ├─ クロージャ変換
                       │                └─ フラグで直接設定
                       │
                       └─ metadata.take()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| metadata.rs | `crates/nu-command/src/debug/metadata.rs` | ソース | metadataコマンド |
| metadata_set.rs | `crates/nu-command/src/debug/metadata_set.rs` | ソース | metadata setコマンド |
| util.rs | `crates/nu-command/src/debug/util.rs` | ソース | 共通ユーティリティ関数 |
| mod.rs | `crates/nu-command/src/debug/mod.rs` | ソース | debugモジュール定義 |
