# 機能設計書 23-文字列トリミング

## 概要

本ドキュメントは、Nushellにおける文字列トリミング機能の設計仕様を記述する。

### 本機能の処理概要

文字列トリミング機能は、文字列の先頭・末尾から空白文字や指定した文字を除去する機能、および文字列の一部を抽出する機能を提供する。データのクレンジング、整形、部分文字列の取得において不可欠な基本操作である。

**業務上の目的・背景**：外部から取り込んだデータには、不要な空白やパディング文字が含まれていることが多い。これらをクレンジングしてデータの正規化を行うため、トリミング機能が必要となる。また、文字列から必要な部分のみを抽出する部分文字列機能も、データ処理において頻繁に使用される。

**機能の利用シーン**：
- ユーザー入力データの前後の空白を除去する場合
- CSVファイルのフィールドに含まれる余分な空白を削除する場合
- 固定長データから特定位置の文字列を抽出する場合
- ファイルパスの拡張子部分のみを取得する場合

**主要な処理内容**：
1. `str trim` - 文字列の前後から空白または指定文字を除去
2. `str substring` - 文字列から指定範囲を抽出

**関連システム・外部連携**：特になし。Nushell内部の文字列処理として動作する。

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

## 関連画面

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

## 機能種別

データ変換 / 整形処理

## 入力仕様

### 入力パラメータ

#### str trim

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --char / -c | String | No | 除去する文字（デフォルト：空白） | 1文字のみ |
| --left / -l | Switch | No | 先頭のみ除去 | - |
| --right / -r | Switch | No | 末尾のみ除去 | - |
| rest | CellPath | No | データ構造内の対象セルパス | - |

#### str substring

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| range | Range | Yes | 抽出範囲のインデックス | - |
| --grapheme-clusters / -g | Switch | No | グラフィムクラスタでカウント | - |
| --utf-8-bytes / -b | Switch | No | UTF-8バイトでカウント（デフォルト） | - |
| rest | CellPath | No | データ構造内の対象セルパス | - |

### 入力データソース

パイプライン入力（文字列、リスト、テーブル、レコード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (str trim) | String | トリミング後の文字列 |
| result (str substring) | String | 抽出された部分文字列 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 文字列、リスト、テーブル、レコードを受け付ける
2. コマンド引数を解析する
   └─ オプションフラグ、範囲指定を取得
3. 入力値の型に応じた処理を実行
   └─ 文字列: 直接処理を適用
   └─ リスト: 各要素に対して処理を適用
   └─ テーブル/レコード: 指定されたセルパスに対して処理を適用
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{コマンド種別}
    B -->|str trim| C[トリム方向判定]
    B -->|str substring| D[範囲解析]
    C --> E{左右指定}
    E -->|left| F[先頭のみトリム]
    E -->|right| G[末尾のみトリム]
    E -->|both| H[両端トリム]
    D --> I{グラフィムモード?}
    I -->|Yes| J[グラフィム単位で抽出]
    I -->|No| K[バイト単位で抽出]
    F --> L[結果出力]
    G --> L
    H --> L
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-23-1 | デフォルト空白文字 | 空白文字にはスペース、タブ、改行、復帰、垂直タブ、フォームフィードを含む | str trim使用時 |
| BR-23-2 | 単一文字制限 | --charオプションは1文字のみ指定可能 | str trim使用時 |
| BR-23-3 | 負のインデックス | 負の値は末尾からの位置を示す | str substring使用時 |
| BR-23-4 | メタデータ除去 | substringの結果からcontent_typeメタデータを除去 | str substring使用時 |

### 計算ロジック

str trimで除去対象となるデフォルト空白文字：
- ' ' (0x20): スペース
- '\t' (0x09): 水平タブ
- '\n' (0x0A): 改行
- '\v' (0x0B): 垂直タブ
- '\f' (0x0C): フォームフィード
- '\r' (0x0D): 復帰

str substringの範囲指定は、negative indexをサポートし、末尾から数えた位置も指定可能。

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

該当なし（メモリ内での文字列処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| GenericError | 複数文字指定 | --charに2文字以上指定された場合 | 1文字のみを指定する |
| UnsupportedInput | 非文字列入力 | セルパス指定時に文字列以外の値 | 文字列値を対象とする |
| OnlySupportsThisInputType | 型エラー | 期待される型以外が入力された場合 | 適切な型を入力する |

### リトライ仕様

該当なし

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

該当なし（ステートレス処理）

## パフォーマンス要件

- グラフィムクラスタ処理はunicode_segmentationクレートを使用
- UTF-8バイト単位処理がデフォルトで、高速な処理を提供

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

特になし

## 備考

- `str trim`、`str substring`はともに定数式として評価可能（is_const = true）
- Unicode対応（グラフィムクラスタ単位での処理が可能）
- グローバルモードでは、レコードやリスト内のすべての文字列値にトリムを適用

---

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

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

### 推奨読解順序

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

トリミングコマンドの引数構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | trim_.rs | `crates/nu-command/src/strings/str_/trim/trim_.rs` | Arguments構造体（7-12行目）、TrimSide enum（20-24行目） |
| 1-2 | substring.rs | `crates/nu-command/src/strings/str_/substring.rs` | Arguments構造体（12-16行目） |

**読解のコツ**: TrimSide enumは、トリム方向（Left, Right, Both）を表現する列挙型。ActionModeは処理モード（Local: セルパス指定時、Global: 全体処理）を示す。

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

コマンド実行の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | trim_.rs | `crates/nu-command/src/strings/str_/trim/trim_.rs` | `impl Command for StrTrim`（26-148行目） |
| 2-2 | substring.rs | `crates/nu-command/src/strings/str_/substring.rs` | `impl Command for StrSubstring`（24-144行目） |

**主要処理フロー**:
1. **78-97行目（trim_.rs）**: `run`メソッドで引数解析
2. **150-194行目（trim_.rs）**: `run`関数でトリム処理の準備と実行

#### Step 3: 処理ロジックを理解する

実際のトリミング・部分文字列抽出ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | trim_.rs | `crates/nu-command/src/strings/str_/trim/trim_.rs` | action関数（202-242行目）- トリム処理の分岐 |
| 3-2 | trim_.rs | `crates/nu-command/src/strings/str_/trim/trim_.rs` | trim関数（244-264行目）- 実際のトリム実行 |
| 3-3 | substring.rs | `crates/nu-command/src/strings/str_/substring.rs` | action関数（146-192行目）- 部分文字列抽出 |

**主要処理フロー**:
- **trim_.rs 244-257行目**: デフォルト空白文字の定義
- **trim_.rs 259-263行目**: TrimSideに応じたトリム処理
- **substring.rs 149-177行目**: グラフィムクラスタまたはバイト単位での抽出

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

```
StrTrim::run
    │
    ├─ call.get_flag("char") - 除去文字取得
    ├─ call.has_flag("left") - 左トリムフラグ
    ├─ call.has_flag("right") - 右トリムフラグ
    │
    └─ run()
           │
           └─ operate()
                  │
                  └─ action()
                         │
                         ├─ Value::String → trim()
                         │      ├─ TrimSide::Left → trim_start_matches
                         │      ├─ TrimSide::Right → trim_end_matches
                         │      └─ TrimSide::Both → trim_matches
                         │
                         └─ Global mode → Record/List再帰処理
```

### データフロー図

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

PipelineData ───▶ operate() ───▶ action() ───▶ Value::String
   │                  │               │
   │                  │               ├─ trim() - 空白/文字除去
   │                  │               │
   │                  └─ セルパス     └─ Global mode
   │                      処理            └─ Record/List処理
   │
   └─ String / List / Table / Record
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| trim_.rs | `crates/nu-command/src/strings/str_/trim/trim_.rs` | ソース | str trim コマンド実装 |
| substring.rs | `crates/nu-command/src/strings/str_/substring.rs` | ソース | str substring コマンド実装 |
| mod.rs | `crates/nu-command/src/strings/str_/trim/mod.rs` | ソース | trimモジュール定義 |
| mod.rs | `crates/nu-command/src/strings/str_/mod.rs` | ソース | str_モジュール定義 |
