# 機能設計書 22-文字列分割・結合

## 概要

本ドキュメントは、Nushellにおける文字列分割・結合機能の設計仕様を記述する。

### 本機能の処理概要

文字列分割・結合機能は、文字列を指定した区切り文字やパターンで分割してリストに変換したり、逆にリストの要素を結合して一つの文字列を生成する機能を提供する。データの解析、変換、整形において基本的かつ重要な操作である。

**業務上の目的・背景**：テキストデータの処理において、CSV、ログファイル、設定ファイルなど区切り文字で構成されたデータを扱う機会は多い。これらのデータを効率的に処理するため、分割と結合の機能が必要となる。パイプラインベースの処理においてデータの形式を柔軟に変換できることが求められる。

**機能の利用シーン**：
- CSVやTSVデータの各フィールドを分割して処理する場合
- ログファイルの行を空白や区切り文字で分割する場合
- 複数の文字列要素を結合して一つのパスや文を構成する場合
- テキストを行単位で分割して個別処理する場合

**主要な処理内容**：
1. `split row` - 区切り文字で文字列を行（要素）に分割
2. `split column` - 区切り文字で文字列を列に分割（テーブル形式）
3. `split chars` - 文字単位で分割
4. `split words` - 単語単位で分割
5. `split list` - リストを分割
6. `str join` - リスト要素を結合して文字列に変換
7. `lines` - 文字列を行単位で分割

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

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

## 関連画面

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

## 機能種別

データ変換

## 入力仕様

### 入力パラメータ

#### split row

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| separator | String | Yes | 分割に使用する区切り文字 | - |
| --regex / -r | Switch | No | 正規表現モードを有効化 | - |
| --number / -n | Int | No | 最大分割数 | 正の整数 |

#### split column

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| separator | String | Yes | 分割に使用する区切り文字 | - |
| rest | String... | No | 列名の指定 | - |
| --collapse-empty / -c | Switch | No | 空の結果を除外 | - |
| --regex / -r | Switch | No | 正規表現モードを有効化 | - |
| --number / -n | Int | No | 最大分割数 | 正の整数 |

#### str join

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| separator | String | No | 結合時に挿入する区切り文字 | - |

### 入力データソース

パイプライン入力（文字列、リスト）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (split row) | List<String> | 分割された文字列リスト |
| result (split column) | Table | 列に分割されたテーブル |
| result (split chars) | List<String> | 文字単位で分割されたリスト |
| result (str join) | String | 結合された文字列 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. パイプラインから入力値を受け取る
   └─ 文字列またはリストを受け付ける
2. コマンド引数を解析する
   └─ 区切り文字、オプションフラグを取得
3. 分割/結合処理を実行
   └─ split: 区切り文字で分割してリスト/テーブルを生成
   └─ join: リスト要素を連結して文字列を生成
4. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{コマンド種別}
    B -->|split row| C[行分割処理]
    B -->|split column| D[列分割処理]
    B -->|split chars| E[文字分割処理]
    B -->|str join| F[結合処理]
    C --> G{正規表現モード?}
    G -->|Yes| H[Regex分割]
    G -->|No| I[通常分割]
    H --> J[結果リスト生成]
    I --> J
    D --> K[テーブル生成]
    E --> L[文字リスト生成]
    F --> M[文字列生成]
    J --> N[出力]
    K --> N
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-22-1 | 正規表現分割 | --regexフラグで正規表現パターンによる分割が可能 | split row/column使用時 |
| BR-22-2 | 最大分割数制限 | --numberフラグで分割数を制限可能 | split使用時 |
| BR-22-3 | 空要素の除外 | --collapse-emptyで空の分割結果を除外 | split column使用時 |
| BR-22-4 | 日付のRFC変換 | str joinで日付値はRFC2822/RFC3339形式で出力 | str join使用時 |

### 計算ロジック

str joinでは、各要素を`to_expanded_string`メソッドで文字列化し、セパレータで連結する。日付値は年が0-9999の範囲内であればRFC2822、それ以外はRFC3339形式で出力される。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | 期待される型以外が入力された場合 | 適切な型を入力する |
| PipelineMismatch | パイプラインエラー | ストリーム内で期待しない型が出現 | 入力データを確認 |

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

- str joinはByteStreamを使用してメモリ効率の良いストリーミング出力を実現
- 大量データの分割時も逐次処理により安定した動作を提供

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

- 正規表現パターン使用時はReDoS攻撃に注意
- 入力データのサイズに上限はないが、メモリ使用量に注意

## 備考

- `str join`は定数式として評価可能（is_const = true）
- ByteStreamを使用した効率的なストリーミング処理を実装

---

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

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

### 推奨読解順序

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

分割・結合コマンドのモジュール構成を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-command/src/strings/split/mod.rs` | splitサブコマンドの一覧（1-13行目） |
| 1-2 | join.rs | `crates/nu-command/src/strings/str_/join.rs` | StrJoin構造体の定義 |

**読解のコツ**: splitは複数のサブコマンド（row, column, chars, words, list）から構成されており、それぞれが異なる分割ロジックを持つ。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | join.rs | `crates/nu-command/src/strings/str_/join.rs` | `impl Command for StrJoin`（10-77行目） |

**主要処理フロー**:
1. **42-51行目**: `run`メソッドでセパレータ取得とrun関数呼び出し
2. **79-132行目**: `run`関数でByteStreamを使用した効率的な結合処理

#### Step 3: ByteStream処理を理解する

ストリーミング出力の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | join.rs | `crates/nu-command/src/strings/str_/join.rs` | ByteStream::from_fn（93-129行目）- ストリーミング出力 |

**主要処理フロー**:
- **93行目**: ByteStream::from_fnでストリーミング出力を構築
- **101-107行目**: 最初の要素以外でセパレータを出力
- **109-123行目**: 値の型に応じた出力処理（エラー、日付、その他）

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

```
StrJoin::run
    │
    ├─ call.opt() - セパレータ取得
    │
    └─ run()
           │
           ├─ input.into_iter()
           │
           └─ ByteStream::from_fn()
                  │
                  └─ buffer への書き込み
                         ├─ separator出力
                         └─ value出力
                               ├─ Date → RFC2822/RFC3339
                               └─ Other → to_expanded_string
```

### データフロー図

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

List<Value> ───▶ ByteStream::from_fn ───▶ PipelineData
   │                    │
   │                    └─ 要素を順次処理
   │                          │
   │                          ├─ separator挿入
   │                          │
   └─ iter.next()             └─ 文字列化
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| join.rs | `crates/nu-command/src/strings/str_/join.rs` | ソース | str join コマンド実装 |
| row.rs | `crates/nu-command/src/strings/split/row.rs` | ソース | split row コマンド実装 |
| column.rs | `crates/nu-command/src/strings/split/column.rs` | ソース | split column コマンド実装 |
| chars.rs | `crates/nu-command/src/strings/split/chars.rs` | ソース | split chars コマンド実装 |
| words.rs | `crates/nu-command/src/strings/split/words.rs` | ソース | split words コマンド実装 |
| list.rs | `crates/nu-command/src/strings/split/list.rs` | ソース | split list コマンド実装 |
| mod.rs | `crates/nu-command/src/strings/split/mod.rs` | ソース | splitモジュール定義 |
