[English](../README.md) | **日本語**

# hanuke

CSV の指定列を連番として検査する CLI ツール。

出現順に「前行の値 + ステップ」であることを検査し、歯抜け（gap）・重複（duplicate）・
逆行やステップ不整合（order violation）を検出する。UNIX 哲学に従い、既定では何も
出力せず終了コードだけで結果を返すため、パイプラインやシェルスクリプトに組み込みやすい。

## インストール

```console
$ cargo install hanuke                # crates.io から
```

Windows / Linux / macOS（および Android）向けのビルド済みバイナリは各
[GitHub リリース](https://github.com/ShortArrow/hanuke/releases)に添付される。
対象アーキテクチャのアーカイブをダウンロードし、`hanuke` を `PATH` に置く。
リリースバイナリはビルド元コミットを埋め込む（`hanuke version --commit`）が、
`cargo install` でのビルドはビルド時に git ツリーが無いため `unknown` になる。

## 終了コード

| code | 意味 |
|------|------|
| 0    | 連番として正常（空ファイル・1行のみも正常とみなす） |
| 1    | 歯抜け・重複・順序違反を検出（既定では stderr に1行だけ要約を出す） |
| 2    | 引数・ファイル IO・パースのエラー |

## 使い方

```console
$ hanuke data.csv                     # 先頭列を10進・ステップ+1で検査
$ hanuke --header data.csv            # 見出し行を読み飛ばす
$ hanuke --col 3 data.csv             # 3列目（1始まり）を検査
$ hanuke --hex data.csv               # 16進（"0x" プレフィックス許容）
$ hanuke --step -1 data.csv           # 降順の連番を検査
$ cat data.csv | hanuke -             # 標準入力から読む
```

### バージョン情報

```console
$ hanuke --version                    # hanuke version でも可
hanuke 0.1.0
$ hanuke version --commit             # ビルド元の git コミットハッシュを付ける
hanuke 0.1.0 (fa49922d9b5f68b91759136dd96b1ff153260469)
```

`--version` / `-V` と `version` サブコマンドは同じ行を出力する。コミットハッシュは
`version --commit` で確認できる（git が無い環境でビルドした場合は `unknown` になる）。

### 対応する CSV パターン

1. **固定バイト幅の hex が複数列**（LE/BE）: `--hex --cols N --endian le|be`
2. **上記の10進版**: `--cols N`（各列は 1 バイト = 0..255。幅は `--col-bytes` で変更）
3. **1列の `0x` 付き hex**: `--hex`
4. **1列のプレフィックスなし hex**: `--hex`
5. **1列の int / uint / 整数値の double**: 既定（`3.0` や `1e3` は整数として受理、`3.5` はエラー）

複数列モードは「1レコードの値が複数列にバイト分割されている」ものとして、
`--endian` に従い結合して1つの整数として比較する。hex の1列あたりバイト数は
先頭データ行の桁数から推定される（明示するなら `--col-bytes`）。

```console
# 00,FE / 00,FF / 01,00 (big endian) → 0x00FE, 0x00FF, 0x0100
$ hanuke --hex --cols 2 --endian be data.csv
```

### 詳細出力

```console
$ hanuke --verbose data.csv
rows: 4
start: 0
end: 5
missing: 2..4
duplicates: 5
issue: row 3: gap: expected 2, got 5 (missing 2..4)
issue: row 4: duplicate value 5
result: NG (2 issue(s))
```

機械可読な出力が必要なら `--json`（OK/NG に関わらず1つの JSON で出力、
終了コードは通常どおり。`jq` などと組み合わせやすい）。
単体では問題の**件数のみ**を含むサイズ有界のサマリを出す:

```console
$ hanuke --json data.csv
{"ok":false,"rows":4,"start":0,"end":5,
 "issue_count":{"total":2,"gap":1,"duplicate":1,"order_violation":0},"missing_count":3}
```

`--verbose` を併用すると `missing` / `duplicates` / `issues` の一覧が加わる
（問題の数に比例して大きくなり得る点に注意）:

```console
$ hanuke --json --verbose data.csv
{"ok":false,"rows":4,"start":0,"end":5,
 "issue_count":{"total":2,"gap":1,"duplicate":1,"order_violation":0},"missing_count":3,
 "missing":[{"first":2,"last":4,"count":3}],"duplicates":[5],
 "issues":[{"type":"gap","row":3,"expected":2,"actual":5,"missing":{"first":2,"last":4,"count":3}},
           {"type":"duplicate","row":4,"value":5}]}
```

issue の `type` は `gap` / `duplicate` / `order_violation` の3種。
`start`・`end` はデータ0行のとき `null`。`missing_count` は歯抜け値の総数。

特定の情報だけが欲しい場合は `--show`（値のみが出力されるのでスクリプトで扱いやすい）:

```console
$ hanuke --show missing data.csv      # 歯抜けの範囲を1行ずつ（例: "5..7"、両端含む）
$ hanuke --show duplicates data.csv   # 重複値を1行ずつ
$ hanuke --show start,end data.csv    # 複数指定時は "start: 10" のようにラベル付き
```

## オプション一覧

| オプション | 既定値 | 説明 |
|-----------|--------|------|
| `-c, --col <N>` | 1 | 検査を開始する列（1始まり） |
| `-n, --cols <N>` | 1 | 1レコードとして読む列数（2以上で結合モード） |
| `-x, --hex` | off | 値を16進として解釈 |
| `--endian <le\|be>` | be | 複数列結合時のバイト順 |
| `--col-bytes <N>` | 推定 | 複数列時の1列あたりバイト数 (1..=16) |
| `--header` | off | 先頭行を見出しとして読み飛ばす |
| `--quote <C>` | `"` | クォート文字（ASCII 1文字。`--quote "'"` でシングルクォート） |
| `-s, --step <N>` | 1 | 期待ステップ（負数で降順、0 は不可） |
| `-v, --verbose` | off | サマリと問題詳細を標準出力へ |
| `--show <KIND>` | なし | start / end / missing / duplicates のみ出力（カンマ区切り可） |
| `--json` | off | 件数サマリを JSON で標準出力へ。`--verbose` 併用で全一覧を含む（`--show` と排他） |

## 入力形式の許容範囲

- 改行コードは LF / CRLF どちらも可（混在も可）。UTF-8 BOM は無視される
- セルのクォートは RFC 4180 準拠（`"a,b"` のようなセル内カンマ、`""` エスケープ）。
  シングルクォート等は `--quote` で指定
- 検査対象のセルだけを UTF-8 として解釈するため、対象外の列に CP932（Shift_JIS）等の
  非 UTF-8 テキストが含まれていても検査できる（対象列は数字＝ASCII である前提）。
  UTF-16 など ASCII 非互換のエンコーディングは非対応

制限: 値は i128 の範囲（複数列結合は合計 16 バイトまで、かつ最上位ビットは符号のため
127 ビットまで）。double 表記は 2^53 以下の整数値のみ受理する。

## ビルドとテスト

```console
$ cargo build --release      # target/release/hanuke.exe
$ cargo test
```

## License

MIT OR Apache-2.0（[LICENSE-MIT](../LICENSE-MIT) / [LICENSE-APACHE](../LICENSE-APACHE)）
