# 機能設計書 81-mimetypes

## 概要

本ドキュメントは、Nim標準ライブラリのmimetypesモジュールに関する機能設計書である。ファイル拡張子からMIMEタイプを判定し、またMIMEタイプから拡張子を逆引きする機能を提供する。

### 本機能の処理概要

mimetypesモジュールは、ファイルの拡張子とMIMEタイプ（メディアタイプ）の相互変換機能を提供するライブラリモジュールである。Webサーバー、HTTPクライアント、ファイルアップロード処理など、ファイルのコンテンツタイプを正確に判定する必要がある場面で利用される。

**業務上の目的・背景**：Webアプリケーションやファイル転送システムにおいて、ファイルのMIMEタイプを正確に判定することは、正しいContent-Typeヘッダの設定、ブラウザによる適切なファイル処理、セキュリティチェックなどに不可欠である。本モジュールは、約1000種類以上のファイル拡張子とMIMEタイプのマッピングデータベースを提供し、開発者が手動でマッピングを管理する必要をなくす。

**機能の利用シーン**：HTTPサーバーでの静的ファイル配信時のContent-Type設定、ファイルアップロード時のバリデーション、ダウンロードリンク生成時のMIMEタイプ指定、Emailの添付ファイル処理など、ファイルの種類を判定する必要がある様々な場面で活用される。

**主要な処理内容**：
1. MimeDBオブジェクトの生成と初期化（デフォルトMIMEタイプマッピングの読み込み）
2. 拡張子からMIMEタイプへの変換（getMimetype関数）
3. MIMEタイプから拡張子への逆引き（getExt関数）
4. カスタムMIMEタイプの登録（register関数）

**関連システム・外部連携**：asynchttpserver、httpclient、net等のネットワークモジュールと連携し、HTTP通信におけるContent-Type処理に利用される。

**権限による制御**：本モジュールは純粋な変換処理であり、権限による制御は行わない。

## 関連画面

該当なし（ライブラリモジュールのため画面との直接的な関連はない）

## 機能種別

データ変換処理 / 辞書参照処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ext | string | Yes | ファイル拡張子（先頭のドットは省略可能） | 空文字列許容、大文字小文字非区別 |
| mimetype | string | Yes | MIMEタイプ文字列 | 空文字列許容、大文字小文字非区別 |
| default | string | No | 見つからない場合のデフォルト値 | - |

### 入力データソース

内部定義された静的MIMEタイプマッピングテーブル（約1000エントリ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MimeDB | object | MIMEタイプデータベースオブジェクト |
| mimetype | string | 変換されたMIMEタイプ文字列 |
| ext | string | 変換されたファイル拡張子 |

### 出力先

呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. newMimetypes()呼び出し
   └─ デフォルトMIMEマッピングテーブルをOrderedTableに変換してMimeDBを生成

2. getMimetype(ext)呼び出し
   └─ 拡張子を小文字変換
   └─ 先頭のドットがあれば除去
   └─ テーブルから検索し、見つかれば返却、なければデフォルト値を返却

3. getExt(mimetype)呼び出し
   └─ MIMEタイプを小文字変換
   └─ テーブル全体を走査して一致するものを検索
   └─ 見つかれば拡張子を返却、なければデフォルト値を返却

4. register(ext, mimetype)呼び出し
   └─ 拡張子とMIMEタイプを小文字変換
   └─ 空文字列チェック（assertで検証）
   └─ テーブルに新規エントリを追加
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|getMimetype| C[拡張子を小文字変換]
    C --> D{先頭にドット?}
    D -->|Yes| E[ドット除去]
    D -->|No| F[テーブル検索]
    E --> F
    F --> G{見つかった?}
    G -->|Yes| H[MIMEタイプ返却]
    G -->|No| I[デフォルト値返却]
    H --> J[終了]
    I --> J

    B -->|getExt| K[MIMEタイプを小文字変換]
    K --> L[テーブル全走査]
    L --> M{見つかった?}
    M -->|Yes| N[拡張子返却]
    M -->|No| O[デフォルト値返却]
    N --> J
    O --> J

    B -->|register| P[入力値検証]
    P --> Q[小文字変換]
    Q --> R[テーブルに追加]
    R --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-81-01 | 大文字小文字非区別 | 拡張子・MIMEタイプは大文字小文字を区別せず検索する | 常時 |
| BR-81-02 | ドット省略可能 | 拡張子の先頭ドットは省略可能 | getMimetype呼び出し時 |
| BR-81-03 | デフォルト値適用 | 見つからない場合はデフォルト値を返却 | 検索失敗時 |

### 計算ロジック

特になし（単純な辞書参照処理）

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

該当なし（インメモリデータ構造を使用）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionDefect | アサーションエラー | register関数で空文字列を渡した場合 | 有効な拡張子/MIMEタイプを指定 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- getMimetype: O(1) - ハッシュテーブル参照
- getExt: O(n) - テーブル全走査（約1000エントリ）
- register: O(1) - ハッシュテーブル挿入

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

- MIMEタイプのなりすましによるセキュリティリスクに注意（ファイル内容の検証は別途必要）
- ユーザー入力をそのまま拡張子として使用する場合はサニタイズが必要

## 備考

- Nim固有の拡張子（.nim, .nimble, .nims, .nimf）がtext/nimとして登録されている
- 本モジュールはfunc（副作用なし関数）で実装されており、コンパイル時計算にも対応

---

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

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

### 推奨読解順序

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

まず、MIMEタイプデータベースの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mimetypes.nim | `lib/pure/mimetypes.nim` | MimeDB型の定義（36-38行目）を確認 |

**読解のコツ**: `OrderedTable[string, string]`を内部に持つシンプルなオブジェクト型。キーが拡張子、値がMIMEタイプ。

#### Step 2: 静的データを理解する

約1000エントリのMIMEマッピングデータの構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mimetypes.nim | `lib/pure/mimetypes.nim` | mimes定数（40-1034行目）の構造を確認 |

**主要処理フロー**:
- **40行目**: `const mimes*`でマッピングデータを定義
- **435-438行目**: Nim固有拡張子の登録（nim, nimble, nimf, nims）

#### Step 3: 主要関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mimetypes.nim | `lib/pure/mimetypes.nim` | newMimetypes関数（1037-1041行目） |
| 3-2 | mimetypes.nim | `lib/pure/mimetypes.nim` | getMimetype関数（1043-1052行目） |
| 3-3 | mimetypes.nim | `lib/pure/mimetypes.nim` | getExt関数（1054-1063行目） |
| 3-4 | mimetypes.nim | `lib/pure/mimetypes.nim` | register関数（1065-1071行目） |

**主要処理フロー**:
- **1037-1041行目**: mimes定数をOrderedTableに変換
- **1047-1048行目**: 先頭ドットの処理と小文字変換
- **1059-1062行目**: 線形探索によるMIMEタイプから拡張子への逆引き

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

```
アプリケーションコード
    │
    ├─ newMimetypes()
    │      └─ mimes.toOrderedTable()
    │
    ├─ getMimetype(ext)
    │      ├─ toLowerAscii(ext)
    │      └─ mimes.getOrDefault()
    │
    ├─ getExt(mimetype)
    │      ├─ toLowerAscii(mimetype)
    │      └─ 線形探索
    │
    └─ register(ext, mimetype)
           └─ mimes[ext] = mimetype
```

### データフロー図

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

ファイル拡張子 ───▶ getMimetype() ───▶ MIMEタイプ文字列
     "mp4"              │                 "video/mp4"
                   toLowerAscii
                   getOrDefault

MIMEタイプ ───▶ getExt() ───▶ ファイル拡張子
"text/html"       │            "html"
              線形探索
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mimetypes.nim | `lib/pure/mimetypes.nim` | ソース | MIMEタイプ判定モジュール本体 |
| tables.nim | `lib/pure/collections/tables.nim` | 依存ライブラリ | OrderedTableの実装 |
| strutils.nim | `lib/pure/strutils.nim` | 依存ライブラリ | toLowerAscii, startsWith等の文字列処理 |
