# 機能設計書 41-パス変換

## 概要

本ドキュメントは、Nushellにおけるパス変換機能（`path expand`および`path relative-to`コマンド）の詳細設計を記載する。これらのコマンドは、ファイルシステムパスの正規化と相対パス計算を提供する。

### 本機能の処理概要

パス変換機能は、ファイルパスの操作において不可欠な機能を提供する。相対パスを絶対パスに展開したり、2つのパス間の相対関係を計算したりすることで、スクリプトやコマンドラインでのファイル操作を容易にする。

**業務上の目的・背景**：シェルスクリプトやコマンドラインでのファイル操作において、パスの正規化は頻繁に必要となる。例えば、`../`や`./`を含むパスを実際の絶対パスに変換することで、ファイルの存在確認やアクセスが確実に行えるようになる。また、バックアップや同期処理では、基準パスからの相対パスを計算してディレクトリ構造を維持する必要がある。

**機能の利用シーン**：
- ユーザーが入力した相対パスを絶対パスに変換してファイル操作を行う場合
- シンボリックリンクを解決して実際のファイルパスを取得する場合
- ディレクトリツリーのコピーや移動時に相対パスを計算する場合
- 設定ファイルで相対パスを使用し、実行時に絶対パスに解決する場合

**主要な処理内容**：
1. `path expand`: 相対パスを絶対パスに展開し、`..`や`.`を解決する
2. `path expand --strict`: パスが存在しない場合にエラーを返す厳密モード
3. `path expand --no-symlink`: シンボリックリンクを解決せずにパスを展開する
4. `path relative-to`: 基準パスからの相対パスを計算する

**関連システム・外部連携**：nu-pathクレートの`canonicalize_with`および`expand_path_with`関数を使用してOSレベルのパス解決を行う。

**権限による制御**：特になし。ただし、`--strict`モード使用時はファイルシステムへのアクセス権限が必要となる。

## 関連画面

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

## 機能種別

計算処理 / パス操作ユーティリティ

## 入力仕様

### 入力パラメータ

#### path expand

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String / List[String] | Yes | 展開対象のパス（パイプライン入力） | 空文字列でも処理される |
| --strict / -s | Switch | No | パスが存在しない場合にエラーを返す | - |
| --no-symlink / -n | Switch | No | シンボリックリンクを解決しない | - |

#### path relative-to

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | String / List[String] | Yes | 相対化対象のパス（パイプライン入力） | 空でないこと |
| path | String | Yes | 基準となる親パス | 入力パスの親であること |

### 入力データソース

パイプライン入力（String型またはList[String]型）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | String / List[String] | 変換後のパス |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. パイプライン入力を受け取る
   └─ String型またはList[String]型を期待
2. フラグ・引数を解析
   └─ strict, no-symlinkフラグ、pathパラメータを取得
3. 各パス値に対してoperate関数を実行
   └─ 入力値をstd::path::Pathに変換し、変換関数を適用
4. 結果を出力
   └─ 変換されたパス文字列を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始: パス入力] --> B{path expandか?}
    B -->|Yes| C{--strict指定?}
    C -->|Yes| D[canonicalize_with実行]
    C -->|No| E[expand_path_with実行]
    D --> F{パス存在?}
    F -->|Yes| G{--no-symlink?}
    F -->|No| H[エラー: パスが存在しない]
    G -->|Yes| I[シンボリックリンク非解決]
    G -->|No| J[シンボリックリンク解決]
    E --> K[結果出力]
    I --> K
    J --> K
    B -->|No: path relative-to| L[expand_to_real_path両パス]
    L --> M[strip_prefix実行]
    M --> N{成功?}
    N -->|Yes| K
    N -->|No| O{大文字小文字非区別FS?}
    O -->|Yes| P[大文字小文字非区別比較]
    O -->|No| Q[エラー: 親パスではない]
    P --> R{成功?}
    R -->|Yes| K
    R -->|No| Q
    H --> S[終了]
    Q --> S
    K --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | パス展開 | 相対パスは現在の作業ディレクトリを基準に絶対パスに変換される | path expand実行時 |
| BR-41-02 | シンボリックリンク解決 | デフォルトでシンボリックリンクは解決される | --no-symlink未指定時 |
| BR-41-03 | 厳密モード | パスが存在しない場合はエラーとなる | --strict指定時 |
| BR-41-04 | 相対パス計算 | 入力パスと基準パスは両方とも絶対パスまたは両方とも相対パスでなければならない | path relative-to実行時 |
| BR-41-05 | 大文字小文字非区別 | Windows/macOSでは大文字小文字を区別しない比較が行われる | path relative-to実行時 |

### 計算ロジック

**path expand**: `canonicalize_with`関数がOSのパス正規化APIを使用し、シンボリックリンクの解決と`..`/`.`の処理を行う。

**path relative-to**: `strip_prefix`メソッドで基準パスを入力パスから除去し、相対パス部分を取得する。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PipelineEmpty | 入力エラー | パイプライン入力が空 | 有効なパス文字列を入力 |
| GenericError | パスエラー | --strict時にパスが存在しない | パスの存在を確認 |
| CantConvert | 変換エラー | 基準パスが入力パスの親でない | 正しい親パスを指定 |
| OnlySupportsThisInputType | 型エラー | String以外の入力 | String型を入力 |

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

ファイルシステムアクセスを伴うため、ネットワークドライブ等では遅延が発生する可能性がある。

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

- パス展開により意図しないディレクトリへのアクセスが発生する可能性があるため、ユーザー入力のパスは慎重に扱う
- シンボリックリンクを介したディレクトリトラバーサルに注意

## 備考

- Windows環境とUnix環境でパスセパレータの扱いが異なる
- macOSではAPFSの大文字小文字非区別設定により動作が変わる可能性がある

---

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

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

### 推奨読解順序

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

パス操作コマンドの共通インターフェースを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-command/src/path/mod.rs` | PathSubcommandArgumentsトレイトとoperate関数の構造を理解する |

**読解のコツ**: `PathSubcommandArguments`トレイトは各パスコマンドの引数構造体が実装するマーカートレイト。`operate`関数が値をPathに変換して処理関数を適用する共通パターン。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | expand.rs | `crates/nu-command/src/path/expand.rs` | PathExpand構造体とCommandトレイト実装 |

**主要処理フロー**:
1. **19-21行目**: コマンド名を"path expand"として定義
2. **23-39行目**: シグネチャ定義（--strict, --no-symlinkスイッチ）
3. **49-70行目**: run関数でArguments構造体を作成し、operate関数を呼び出し
4. **144-185行目**: expand関数で実際のパス展開処理を実行

#### Step 3: path relative-toを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | relative_to.rs | `crates/nu-command/src/path/relative_to.rs` | PathRelativeTo構造体と相対パス計算ロジック |

**主要処理フロー**:
- **144-169行目**: relative_to関数でstrip_prefixを使用した相対パス計算
- **172-175行目**: is_case_insensitive_filesystem関数でOS判定
- **178-226行目**: try_case_insensitive_strip_prefix関数で大文字小文字非区別の比較

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

```
path expand
    │
    ├─ PathExpand::run
    │      └─ super::operate
    │             └─ expand(path, span, args)
    │                    ├─ canonicalize_with (--strict時)
    │                    └─ expand_path_with (通常時)
    │
path relative-to
    │
    ├─ PathRelativeTo::run
    │      └─ super::operate
    │             └─ relative_to(path, span, args)
    │                    ├─ expand_to_real_path (両パス)
    │                    ├─ lhs.strip_prefix(&rhs)
    │                    └─ try_case_insensitive_strip_prefix (フォールバック)
```

### データフロー図

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

String ───▶ std::path::Path ───▶ パス展開/相対化 ───▶ String
  │              │                      │
  └── span情報 ──┘                      └── Value::string
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| expand.rs | `crates/nu-command/src/path/expand.rs` | ソース | path expandコマンド実装 |
| relative_to.rs | `crates/nu-command/src/path/relative_to.rs` | ソース | path relative-toコマンド実装 |
| mod.rs | `crates/nu-command/src/path/mod.rs` | ソース | パスコマンド共通処理とモジュール定義 |
| expand.rs | `tests/path/expand_path.rs` | テスト | パス展開のテスト |
