# 機能設計書 42-設定切り替え (served/switchConfig)

## 概要

本ドキュメントは、serve-d LSPサーバーが提供するカスタムLSPメソッド `served/switchConfig` の機能設計を記述する。このメソッドは、DUBプロジェクトのビルド設定（configuration）を指定された設定に切り替え、インポートパスを更新する。

### 本機能の処理概要

**業務上の目的・背景**：DUBプロジェクトでは複数のビルド設定を定義でき（例：application、library、unittest等）、設定によってインポートパスやビルドフラグが異なる。開発者がビルド設定を切り替えた際に、DCDの自動補完やインポートパスの解決が正しく動作するように、serve-dの内部状態を更新する必要がある。本機能はその切り替えを担う。

**機能の利用シーン**：エディタのステータスバーやコマンドパレットからビルド設定を選択した際に呼び出される。No.41（設定一覧取得）で取得した一覧から選択された設定名をパラメータとして送信する。

**主要な処理内容**：
1. アクティブなワークスペースインスタンスとDubComponentの有効性確認
2. 指定された設定名をDubComponentに設定
3. DubComponent内部でインポートパスの再計算

**関連システム・外部連携**：workspace-dサブパッケージのDubComponentを介してDUBのプロジェクト設定を変更する。設定変更後、インポートパスが自動更新される。

**権限による制御**：特に権限制御はない。アクティブインスタンスまたはDubComponentが存在しない場合はfalseを返却する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 43 | 設定切り替え（served/switchConfig） | 主画面 | DUBビルド設定を指定された設定に切り替える |

## 機能種別

設定変更（UPDATE）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| value | SwitchConfigParams (string) | Yes | 切り替え先のビルド設定名。JSON文字列またはオブジェクト `{"value": "設定名"}` の両形式に対応 | DUBプロジェクトに存在する設定名であること |

### 入力データソース

LSPクライアントからの `served/switchConfig` リクエスト。SwitchConfigParams型は `SingleValueParams!string` ミキシンにより、文字列直値またはオブジェクト形式の両方を受け付ける。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | bool | 設定切り替えが成功した場合true、失敗した場合false |

### 出力先

LSPクライアントへのJSON-RPCレスポンスとして返却。

## 処理フロー

### 処理シーケンス

```
1. アクティブインスタンスの確認
   └─ activeInstanceがnullの場合、falseを返却して終了
2. DubComponentの有効性確認
   └─ activeInstance.has!DubComponentがfalseの場合、falseを返却して終了
3. ビルド設定の切り替え
   └─ DubComponent.setConfiguration(value)を呼び出し
      ├─ 指定設定がconfigurationsに存在するか確認
      ├─ 存在しない場合falseを返却
      ├─ _configurationに設定名を保存
      ├─ _settingsTemplateを更新
      └─ updateImportPaths(false)でインポートパスを再計算
4. 結果の返却
   └─ bool値をクライアントに返却
```

### フローチャート

```mermaid
flowchart TD
    A[served/switchConfig リクエスト受信] --> B{activeInstance が有効か?}
    B -->|No| C[false を返却]
    B -->|Yes| D{DubComponent が有効か?}
    D -->|No| C
    D -->|Yes| E[DubComponent.setConfiguration 呼び出し]
    E --> F{設定がconfigurationsに存在するか?}
    F -->|No| C
    F -->|Yes| G[_configuration を更新]
    G --> H[_settingsTemplate を更新]
    H --> I[updateImportPaths で再計算]
    I --> J[結果を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | アクティブインスタンス必須 | アクティブなワークスペースインスタンスが存在しない場合はfalseを返す | 常時 |
| BR-42-02 | DubComponent必須 | DubComponentがロードされていない場合はfalseを返す | 常時 |
| BR-42-03 | 設定名の妥当性確認 | 指定された設定名がDUBプロジェクトのconfigurationsに含まれていること | setConfiguration呼び出し時 |
| BR-42-04 | インポートパスの自動更新 | 設定切り替え後、updateImportPaths(false)が自動的に呼び出される | 設定切り替え成功時 |

### 計算ロジック

特別な計算ロジックはない。

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

本機能はデータベースを使用しない。DubComponentのインメモリ状態を変更する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的エラー | activeInstanceがnull | falseを返却 |
| - | 暗黙的エラー | DubComponentが未ロード | falseを返却 |
| - | 検証エラー | 指定設定名がconfigurationsに存在しない | falseを返却 |

### リトライ仕様

リトライ処理はない。

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

トランザクション制御はない。設定変更は即時反映される。

## パフォーマンス要件

設定変更後にupdateImportPathsが呼び出されるため、プロジェクト規模に応じた遅延が発生する可能性がある。

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

特になし。ローカルプロジェクト設定の変更のみ。

## 備考

- SwitchConfigParamsはSingleValueParamsミキシンを使用しており、JSON文字列 `"foo"` またはオブジェクト `{"value":"foo"}` の両方をデシリアライズできる。
- 設定切り替え後のインポートパス更新は同期的に行われる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | SwitchConfigParams構造体（491-494行目）。SingleValueParams!stringミキシンにより柔軟なデシリアライズに対応 |
| 1-2 | protoext.d | `source/served/lsp/protoext.d` | SingleValueParamsミキシンテンプレート（422-488行目）のデシリアライズロジック |

**読解のコツ**: D言語のmixin templateは、構造体にメンバーとメソッドを注入する仕組み。SingleValueParamsは`deserializeFromIon`メソッドを注入し、値そのものとオブジェクト形式の両方からのデシリアライズを可能にする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dub.d | `source/served/commands/dub.d` | switchConfig関数（33-39行目）がエントリーポイント |

**主要処理フロー**:
1. **33行目**: `@protocolMethod("served/switchConfig")` でLSPメソッドとして登録
2. **34行目**: 引数として `SwitchConfigParams value` を受け取る
3. **36-37行目**: activeInstanceとDubComponentの存在確認
4. **38行目**: `DubComponent.setConfiguration(value)` を呼び出し（SwitchConfigParamsのalias thisにより暗黙的にstring変換）

#### Step 3: DubComponent.setConfigurationの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `workspace-d/source/workspaced/com/dub.d` | setConfiguration関数（523-530行目） |

**主要処理フロー**:
- **525行目**: `_dub.project.configurations.canFind(configuration)` で設定名の妥当性を検証
- **527行目**: `_configuration = configuration` で内部状態を更新
- **528行目**: `_settingsTemplate` をルートパッケージの設定で更新
- **529行目**: `updateImportPaths(false)` でインポートパスを再計算

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

```
served/switchConfig (LSPリクエスト)
    │
    └─ switchConfig(SwitchConfigParams) [source/served/commands/dub.d:34-39]
           │
           ├─ activeInstance チェック
           ├─ has!DubComponent チェック
           │
           └─ DubComponent.setConfiguration(string) [workspace-d/source/workspaced/com/dub.d:523-530]
                  │
                  ├─ _dub.project.configurations.canFind() (設定名妥当性確認)
                  ├─ _configuration = configuration (内部状態更新)
                  ├─ getBuildSettings() (設定テンプレート更新)
                  └─ updateImportPaths(false) (インポートパス再計算)
```

### データフロー図

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

SwitchConfigParams ───> switchConfig() ───> bool (成否)
  (設定名string)              │
                         DubComponent
                         .setConfiguration()
                              │
                         updateImportPaths()
                              │
                         インポートパス再計算
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | LSPメソッドのエントリーポイント（switchConfig関数） |
| dub.d | `workspace-d/source/workspaced/com/dub.d` | ソース | DubComponent.setConfigurationの実装 |
| protoext.d | `source/served/lsp/protoext.d` | ソース | SwitchConfigParams、SingleValueParamsの定義 |
| types.d | `source/served/types.d` | ソース | activeInstance、backend等のグローバル状態管理 |
| extension.d | `source/served/extension.d` | ソース | コマンドモジュールのpublic import |
