From 2e96d174f25c96521cab07bfaca2d9a7d029c8a1 Mon Sep 17 00:00:00 2001 From: Luno Date: Sat, 18 Jul 2026 16:25:50 +0900 Subject: [PATCH] Document conversion internals and limits --- README.md | 22 ++++++++++++++++++++++ docs/architecture.md | 42 ++++++++++++++++++++++++++++++++++-------- docs/development.md | 8 ++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8bb36f0..07e523d 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,26 @@ id items[0].qty items[0].sku user.name 逆方向の変換では、`user.name` や `items[0].sku` のような列名から入れ子の map/arrayを復元します。 +列パスは `.` でmapのキー、`[n]` で0始まりの配列indexを表します。たとえば +`orders[0].items[1].sku` は、最初の注文に含まれる2番目の商品の `sku` です。 + +同じ行に `user` と `user.name` のような競合する列がある場合、先に読み込まれた +値を保持し、後続列で型を上書きしません。曖昧な復元を避けるため、親要素と子要素を +同時に列として置かないでください。 + +## セル値の型推定 + +CSV、TSV、XLSXから構造化形式へ戻す際は、セル文字列を次の順で推定します。 + +- 空文字は空文字列 +- `true` / `false` はboolean +- 通常の整数は64-bit integer +- 小数点または指数表記を含む数値は64-bit floating point +- それ以外は文字列 + +郵便番号や商品コードを想定し、`00123` や `-01` のようなゼロ埋め値は文字列のまま +保持します。日付、時刻、`null` は自動推定しません。 + ## CLIオプション - `-i`: 入力ファイル。省略時はstdin。 @@ -125,6 +145,8 @@ map/arrayを復元します。 - 表形式では1行目をヘッダーとして扱います。 - XLSXは指定した1シートのみ読み書きします。 - セル値の型推定は、空文字、真偽値、整数、小数、文字列の範囲です。 +- 空のmap/arrayは表側で `{}` / `[]` と表示されますが、逆変換時は文字列になります。 +- mapキーに `.`、`[`、`]` を含む場合のescape記法は未対応です。 - 複雑なExcel書式や数式の保持は目的外です。 ## 開発者向け情報 diff --git a/docs/architecture.md b/docs/architecture.md index e164532..b2b6b78 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -12,17 +12,22 @@ - table -> structured - table -> table -## Format Adapters +## Source Layout -各形式の処理は `cmd/dataxl/main.go` の以下の関数に集約しています。 +実装は `cmd/dataxl` package内で責務別に分割しています。 -- `parseStructured` -- `encodeStructured` -- `parseTable` -- `encodeTable` +- `main.go`: CLI option、stdin/stdout、ファイル入出力 +- `conversion.go`: 変換経路の選択、形式名の正規化・推定 +- `structured.go`: JSON/YAML/TOML adapter +- `table.go`: CSV/TSV/XLSX adapter、table model、flatten +- `path.go`: セル値の型推定、列パスのparse、unflatten -現在はCLIが小さいため単一ファイルに置いています。形式やオプションが増えたら、 -`internal/format` や `internal/table` へ分割する余地があります。 +`convert` はファイル入出力から独立しているため、CLIを経由せず変換matrixをテストできます。 +形式固有処理は `parseStructured` / `encodeStructured` または +`parseTable` / `encodeTable` に閉じ込めます。 + +現状は単一commandだけが利用するため同じpackageに置いています。別commandやlibrary APIから +再利用する段階になったら、安定させたい境界を見極めたうえで `internal` packageへ移します。 ## Table Model @@ -79,6 +84,21 @@ items[0].sku - 小数または指数表記: float64 - その他: string +ゼロ埋め整数は、IDやコードを壊さないためstringとして保持します。複数列が同じパスで +異なる中間型を要求する場合は、先に構築された値を後続列で上書きしません。 + +### Path grammar + +現在の列パスは次の要素を扱います。 + +```text +path = key, { ".", key | "[", index, "]" }; +index = digit, { digit }; +``` + +実例は `user.name`、`items[0].sku`、`orders[0].items[1].qty` です。 +区切り文字を含むmap keyのescapeは未対応です。 + ## TOML Output TOMLはトップレベル配列を直接表せないため、表からTOMLへ出力する場合など、 @@ -91,3 +111,9 @@ TOMLはトップレベル配列を直接表せないため、表からTOMLへ出 - `github.com/BurntSushi/toml`: TOML読み書き Go 1.24以上を前提にしています。 + +## Error handling + +- 未対応形式、decode失敗、workbook/sheet操作失敗は呼び出し元へerrorを返します。 +- path復元中の型競合は既存値を保護するため、その列の適用を中止します。 +- XLSXのstyle・pane設定も通常の変換errorとして扱い、不完全なworkbookを成功扱いしません。 diff --git a/docs/development.md b/docs/development.md index c3beab1..1e2ce1b 100644 --- a/docs/development.md +++ b/docs/development.md @@ -51,6 +51,11 @@ The current tests cover: - YAML -> TSV flattening - TSV -> JSON path restoration - JSON -> XLSX -> JSON round trip +- structured -> structured conversion without CLI/file I/O +- extension normalization and format inference +- ragged table row padding +- conservative cell type inference, including zero-padded identifiers +- conflicting unflatten paths When adding a new format or path rule, add tests around both directions where possible. @@ -96,3 +101,6 @@ go install git.rumginger.org/agent/dataxl/cmd/dataxl@v0.1.0 - Preserve headers as the contract between spreadsheet data and structured data. - Prefer explicit errors over silent best-effort conversion when a format is unsupported. - Keep dependencies small unless a format needs a mature parser/writer. +- Keep CLI/file I/O in `main.go`; conversion behavior should remain testable through `convert`. +- Keep format-specific behavior in its structured or table adapter. +- Document round-trip limitations when a representation cannot preserve a value exactly.