tabkit 0.4.0

Tabular files → schema + sample rows. The shared spreadsheet reader Tauri / Iced / native desktop apps reach for when they need to introspect XLSX / CSV / TSV without inventing the same calamine-plus-type-inference glue twice.
Documentation
[package]
name = "tabkit"
version = "0.4.0"
edition = "2021"
rust-version = "1.85"
authors = ["tabkit contributors"]
description = "Tabular files → schema + sample rows. The shared spreadsheet reader Tauri / Iced / native desktop apps reach for when they need to introspect XLSX / CSV / TSV without inventing the same calamine-plus-type-inference glue twice."
documentation = "https://docs.rs/tabkit"
homepage = "https://github.com/seryai/tabkit"
repository = "https://github.com/seryai/tabkit"
license = "MIT OR Apache-2.0"
readme = "README.md"
keywords = ["xlsx", "csv", "spreadsheet", "schema", "tabular"]
categories = ["parser-implementations", "data-structures"]
exclude = [
    "/.github",
    "/tests/fixtures/large/*",
]

[features]
# The default set is the in-process pure-Rust readers — small, fast,
# zero runtime deps. ~1 MB compiled.
default = ["calamine", "csv"]

# In-process Rust backends.
calamine = ["dep:calamine"]   # XLSX / XLS / XLSB / XLSM / ODS via the calamine crate
csv      = ["dep:csv"]        # CSV / TSV via the csv crate
parquet  = ["dep:parquet"]    # Parquet via the apache parquet crate (no Arrow runtime needed for read)

# Build-everything convenience for downstream tests.
full = ["calamine", "csv", "parquet"]

[dependencies]
thiserror = "2"

# Optional backends. Each is gated by the corresponding feature flag
# above; consumers pay only for the surface they enable.
calamine = { version = "0.34", optional = true }
csv      = { version = "1", optional = true }
# Apache Parquet read support. We disable default features so we
# don't pull in the full Arrow runtime, the async-reader, and the
# CLI tools — none of which `tabkit`'s schema-and-samples surface
# needs. Just the plain row reader.
parquet  = { version = "56", optional = true, default-features = false }

[dev-dependencies]
tempfile = "3"

[lints.rust]
# `forbid` rather than `deny` — there's no FFI in this crate, so any
# `unsafe` block is a bug to fix at review time, not a justified
# opt-in.
unsafe_code = "forbid"
missing_docs = "warn"

[lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
# Selectively allow the pedantic lints that fight common idioms.
module_name_repetitions = "allow"
must_use_candidate = "allow"
missing_errors_doc = "allow"