# 通知設計書 25-served/convertDubFormat

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるカスタム通知「served/convertDubFormat」の設計仕様を定義する。本通知はクライアント(エディタ)からサーバーに送信され、DUBレシピファイルのフォーマット変換（JSON <-> SDL）を実行する。

### 本通知の処理概要

本通知は、DUBパッケージ管理システムのレシピファイル（dub.json / dub.sdl）を別のフォーマットに変換するものである。

**業務上の目的・背景**：DUBはD言語のパッケージ管理兼ビルドツールであり、プロジェクト設定をJSON形式（dub.json）またはSDL形式（dub.sdl）で記述できる。プロジェクトの要件やチームの好みに応じてフォーマットを変換する必要がある場合に、エディタ上から直接変換を実行できる機能を提供する。

**通知の送信タイミング**：ユーザーがエディタのコマンドパレットから「Convert DUB Format」を実行し、変換先フォーマット（json/sdl）を指定したときに送信される。

**通知の受信者**：serve-d LSPサーバープロセスが受信者である。

**通知内容の概要**：DubConvertRequestをパラメータとして受け取る。textDocument（変換元ファイルのURI）とnewFormat（変換先フォーマット文字列）を含む。

**期待されるアクション**：サーバーはdubコマンドを使用してフォーマット変換を実行し、workspace/applyEditリクエストでクライアントのファイルを更新する。必要に応じてファイルのリネーム（拡張子変更）も行う。

## 通知種別

LSPカスタム通知（JSON-RPC Notification）。クライアントからサーバーへの方向（C->S）。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（JSON-RPC notification） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

クライアントがserve-d LSPサーバーに直接送信する。

## 通知テンプレート

### メール通知の場合

該当なし。本通知はLSPプロトコル上のJSON-RPCメッセージである。

### 本文テンプレート

```json
{
  "jsonrpc": "2.0",
  "method": "served/convertDubFormat",
  "params": {
    "textDocument": {
      "uri": "file:///path/to/dub.json"
    },
    "newFormat": "sdl"
  }
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| textDocument.uri | 変換元ファイルのURI | クライアント指定 | Yes |
| newFormat | 変換先フォーマット（"json" / "sdl"） | ユーザー選択 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | ユーザーが「Convert DUB Format」コマンドを実行 | アクティブファイルがdub.json/dub.sdl/package.json | DUBレシピフォーマット変換 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ファイル未存在 | 指定ファイルが存在しない場合はエラーログ出力して終了 |
| 非レシピファイル | dub.json/dub.sdl/package.json以外の場合はエラーメッセージ表示 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[served/convertDubFormat通知受信] --> B{ファイル存在?}
    B -->|No| C[エラーログ出力・終了]
    B -->|Yes| D{レシピファイル?}
    D -->|No| E[window/showErrorMessage表示]
    D -->|Yes| F[dub convert実行]
    F --> G{変換成功?}
    G -->|No| H[window/showErrorMessage表示]
    G -->|Yes| I{リネーム対応可能?}
    I -->|Yes| J[DocumentChanges: リネーム + テキスト編集]
    I -->|No| K[テキスト編集のみ]
    J --> L[workspace/applyEdit送信]
    K --> L
    L --> M[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし。

### 更新テーブル一覧

該当なし。ファイルシステム上のDUBレシピファイルが更新される。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ファイル未存在 | 指定URIのファイルがない | エラーログ出力して処理終了 |
| 非レシピファイル | dub.json/dub.sdl/package.json以外 | window/showErrorMessageで通知 |
| 変換失敗 | dubコマンドの終了コードが0以外 | window/showErrorMessageで通知 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

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

- dubコマンドが外部プロセスとして実行される（execute関数）
- stderrPassThroughオプションが設定されており、標準エラー出力がそのまま通過する
- 最大4MBの出力制限あり（1024 * 1024 * 4）

## 備考

- 変換処理はdubコマンドの`dub convert -f <format> -s`を使用して実行される
- クライアントがresourceOperations.renameをサポートする場合、ファイルリネームとテキスト編集が一つのWorkspaceEditで行われる
- サポートしない場合は元のファイルに対するテキスト編集のみが適用される
- workspace/applyEditリクエストでクライアント側に変更を適用する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | DubConvertRequestの定義（textDocument, newFormat） |
| 1-2 | protocol.d | `protocol/source/served/lsp/protocol.d` | WorkspaceEdit、ApplyWorkspaceEditParams、RenameFileの定義 |

**読解のコツ**: DubConvertRequestはtextDocumentとnewFormatの2フィールドを持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dub.d | `source/served/commands/dub.d` | convertDubFormat関数（L513-572） |

**主要処理フロー**:
1. **L513**: `@protocolNotification("served/convertDubFormat")` アノテーション
2. **L514**: `void convertDubFormat(DubConvertRequest req)` シグネチャ
3. **L518-523**: ファイル存在チェック
4. **L525-529**: レシピファイルチェック（dub.json/dub.sdl/package.json）
5. **L533-536**: dub convertコマンド実行
6. **L538-541**: 変換結果チェック
7. **L544**: 新しいURIの生成（拡張子変更）
8. **L546-571**: WorkspaceEditの構築とworkspace/applyEdit送信

#### Step 3: workspace/applyEdit送信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `source/served/commands/dub.d` | L546-572 resourceOperationsの判定とWorkspaceEdit構築 |

**主要処理フロー**:
- **L551-555**: resourceOperations.renameサポート時はdocumentChanges使用
- **L557-563**: RenameFile + TextDocumentEditをdocumentChangesに設定
- **L566**: 非サポート時はchangesに直接設定
- **L568-571**: ApplyWorkspaceEditParamsを構築してrpc.sendMethod実行

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

```
[クライアント] served/convertDubFormat通知
    |
    +-- RPCProcessor
          |
          +-- convertDubFormat() [dub.d L514]
                |
                +-- fs.exists() (ファイル存在チェック)
                |
                +-- execute(["dub", "convert", ...]) (外部コマンド)
                |
                +-- rpc.sendMethod("workspace/applyEdit", ...) (編集適用)
```

### データフロー図

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

DubConvertRequest        convertDubFormat()                workspace/applyEdit
(uri, newFormat)  -----> dub convertコマンド実行        --> (WorkspaceEdit)
                         WorkspaceEdit構築
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | convertDubFormat通知ハンドラ（L513-572） |
| types.d | `source/served/types.d` | ソース | DubConvertRequestの型定義 |
| protocol.d | `protocol/source/served/lsp/protocol.d` | ソース | WorkspaceEdit、ApplyWorkspaceEditParams型定義 |
| jsonrpc.d | `lsp/source/served/lsp/jsonrpc.d` | ソース | sendMethodによるworkspace/applyEdit送信 |
| translate.d | `source/served/utils/translate.d` | ソース | エラーメッセージの翻訳 |
