[package]
name = "fits-well"
version = "0.1.3"
edition = "2024"
rust-version = "1.85"
description = "A blazing-fast reader and writer for FITS (Flexible Image Transport System) files, targeting the full FITS 4.0 standard."
license = "MIT OR Apache-2.0"
repository = "https://github.com/xorza/fits"
readme = "README.md"
keywords = ["fits", "astronomy", "image", "fileformat"]
categories = ["science", "parser-implementations"]
# Keep the published tarball lean: the ~11 MiB of test fixtures, the verbatim FITS
# standard reference (incl. a 1.1 MiB PDF), and editor/AI dev notes aren't needed to
# build or use the crate. Source, examples, benches, README, and licenses stay in.
exclude = [
    "docs/",
    "tests/",
    ".claude/",
    "CLAUDE.md",
    "todo.txt",
]

# Render docs.rs with every user-facing feature so WCS, compression, mmap, and the
# ndarray bridge all appear. `internals` is intentionally omitted — it re-exposes
# unstable bench-only entry points that shouldn't surface in the public docs.
[package.metadata.docs.rs]
features = ["compression", "parallel", "mmap", "ndarray"]
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
# Always-on core dependencies (the corresponding column kinds aren't feature-gated):
# `bitvec` backs `X` bit-array columns, `num-complex` the `C`/`M` complex columns.
bitvec = "1"
num-complex = "0.4"
flate2 = { version = "1.1", optional = true }
rayon = { version = "1", optional = true }
memmap2 = { version = "0.9", optional = true }
ndarray = { version = "0.17", optional = true }

[dev-dependencies]
criterion = "0.8"

[features]
default = ["parallel", "compression"]
# rayon-backed tile-parallel (de)compression — the codecs are compute-bound and
# tiles are independent, so this scales near-linearly. Scalar fallback otherwise.
# (The raw byte-swap / BSCALE-BZERO paths are memory-bound; SIMD is their lever,
# not threads, so they are deliberately not parallelized.) Implies `compression`,
# since the codecs are the only thing parallelized.
parallel = ["compression", "dep:rayon"]
# memory-mapped read sources (via memmap2) for zero-copy access over large files:
# data units decode straight from the mapped pages, skipping the staging copy.
mmap = ["dep:memmap2"]
# n-dimensional image arrays (via ndarray): `Image`/`RawImage` -> typed `ImageArray`
# or a physical `ArrayD<f64>`, in FITS axis order, zero-copy where possible.
ndarray = ["dep:ndarray"]
# tiled image + table (de)compression: all five image codecs (GZIP_1, GZIP_2,
# RICE_1, PLIO_1, HCOMPRESS_1) plus §10.3 tables. Pulls in flate2 for the gzip
# codecs. The WCS (§8) and time (§9) layers are dependency-free and always compiled.
compression = ["dep:flate2"]
# Re-expose the hot internal decode/encode entry points for microbenchmarks only.
# NOT a stable API surface — the benches under `benches/` enable it.
internals = []

# Throughput benchmarks: `cargo bench --features internals`. The data unit is
# black-boxed and tagged with `Throughput::Bytes`, so results read in GiB/s and are
# directly comparable to memory bandwidth.
[[bench]]
name = "decode"
harness = false
required-features = ["internals"]

# Compression-codec throughput (`cargo bench --features compression --bench compress`),
# reported in uncompressed bytes/s so it's comparable to the raw `decode` numbers.
[[bench]]
name = "compress"
harness = false
required-features = ["compression"]

# Read-path throughput: seeking (copy-into-scratch) vs in-memory borrow. Uses only
# the public API; the mmap arm is `#[cfg]`-gated on the `mmap` feature.
[[bench]]
name = "read"
harness = false

# The `compression` example uses the tiled-compression API, so it only builds with
# that feature (the others are auto-discovered and feature-free).
[[example]]
name = "compression"
required-features = ["compression"]

# The `ndarray` example uses the n-D array API, gated on the `ndarray` feature.
[[example]]
name = "ndarray"
required-features = ["ndarray"]
