Skip to content

[Feature] 検索結果出力フォーマッター(human / json / path) #8

@Kewton

Description

@Kewton

概要

検索結果を human / json / path の3形式で出力するフォーマッターを実装する。

背景・動機

CLI出力の多様な用途(目視確認、プログラム連携、パイプ連携)に対応するため。--format フラグで切り替える。

提案する解決策

src/output/ モジュールとして以下を実装する。

human 形式(デフォルト)

docs/auth.md:12 [## 認証フロー]
  認証はJWTベースで行い、セッション管理には...
  Tags: auth, security

docs/api.md:45 [### エンドポイント]
  /api/auth/login にPOSTリクエストを...
  • ファイルパス:行番号 [見出し] の形式
  • 本文スニペット(最大2行、超過時は末尾に「...」を付与。改行がない場合は先頭120文字で切り詰め)
  • タグがあれば表示(カンマ区切り)
  • ターミナル色付き出力(colored クレートを使用)
  • score は human 形式では非表示

json 形式(JSONL)

{"path":"docs/auth.md","heading":"認証フロー","heading_level":2,"body":"認証はJWTベースで...","tags":["auth","security"],"line_start":12,"score":1.5}
{"path":"docs/api.md","heading":"エンドポイント","heading_level":3,"body":"/api/auth/login に...","tags":[],"line_start":45,"score":1.2}
  • SearchResult.tags(スペース区切り文字列)を split してJSON配列に変換する
  • 空文字列の場合は空配列 [] を出力
  • score フィールドを含む(検索スコアの伝達用)

path 形式

docs/auth.md
docs/api.md
  • ファイルパスのみ(重複除去)

実装詳細

SearchResult の利用

  • 既存の indexer::reader::SearchResult をそのまま利用する(重複定義しない)
  • JSON出力のために SearchResultserde::Serialize derive を追加する
  • tags フィールド(String型)のJSON配列化はフォーマッター側で変換処理を行う

tags 変換ルール

  • SearchResult.tags はスペース区切り文字列(例: "auth security"
  • JSON出力時: split_whitespace()Vec<String> に変換して配列出力
  • human出力時: カンマ区切り(例: Tags: auth, security
  • 空文字列の場合: JSON は空配列 []、human はタグ行自体を非表示

エラー型

  • OutputError enum を src/output/mod.rs に定義
  • Io(std::io::Error) / Json(serde_json::Error) バリアントを含む
  • std::error::Error + Display + From 変換を実装

CLI --format フラグ

  • src/main.rs の Search サブコマンドに --format オプションを追加
  • OutputFormat enum(Human, Json, Path)を src/output/mod.rs で定義
  • clap の ValueEnum derive で直接パース
  • デフォルト値は OutputFormat::Humandefault_value_t 使用)

色付き出力の制御

  • colored クレート(バージョン 2)を使用
  • NO_COLOR 環境変数によるANSIエスケープ無効化に対応(colored crateの標準機能)
  • パイプ出力時のANSIコード抑制を考慮

スニペット切り詰めルール

  • body を改行(\n)で分割し、最大2行を取得
  • 3行目以降がある場合は末尾に「...」を付与
  • 改行がない場合のフォールバック: 先頭120文字で切り詰め、超過時に「...」を付与

受け入れ基準

  • --format human でカラー付き・スニペット付きの出力ができる
  • --format json で JSONL 形式の出力ができる(score 含む)
  • --format path でファイルパスのみの出力ができる(重複除去)
  • フラグ未指定時は human がデフォルト
  • 既存CLIテスト(search関連)が引き続きパスする
  • cargo test / clippy / fmt 全パス

影響範囲

新規ファイル

  • src/output/mod.rs — モジュール定義・OutputFormat enum・OutputError enum
  • src/output/human.rs — Human形式フォーマッター
  • src/output/json.rs — JSONL形式フォーマッター
  • src/output/path.rs — Path形式フォーマッター
  • tests/output_format.rs — 出力フォーマットテスト

既存ファイルの変更

  • src/main.rs — Search サブコマンドに --format オプション追加
  • src/lib.rspub mod output; の有効化
  • src/indexer/reader.rsSearchResultSerialize derive 追加
  • Cargo.tomlcolored = "2" クレート追加

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions