vsf 0.4.2

Versatile Storage Format
Documentation
[package]
name = "vsf"
version = "0.4.2"
edition = "2021"
authors = ["Nick Spiker <nick@verichrome.cc>"]
description = "Versatile Storage Format"
license-file = "LICENSE"
repository = "https://github.com/nickspiker/vsf"
keywords = ["binary", "serialization", "storage", "data-format"]
categories = ["encoding", "data-structures"]
exclude = [
    "*.rlib",            # Build artifacts
    "*.vsf",             # Example VSF files
    "vsf.png",           # Logo (GitHub only, not needed in package - 1.5MB)
    "target/",           # Build directory
    "tools/",            # Code generation tools
    "frequencies.bin",   # 8.5MB corpus — only needed by offline codebook regen, not at runtime
    "test_determinism",  # Local debug artifacts (compiled binary + source)
    "test_determinism.rs",
]
# huffman_codes.bin (~8.5MB) is vendored in the published crate — verified by BLAKE3 in
# build.rs at every build. It IS the wire format for VsfType::x; any drift silently
# bifurcates the identity namespace via ihi.
#
# frequencies.bin is the input corpus from which huffman_codes.bin is derived. It's NOT
# shipped in the published crate (size budget + the corpus is the SOURCE, not the RUNTIME
# artifact). build.rs verifies it when present (developers from git clone) and skips the
# check when absent (end-users from crates.io). To regenerate the codebook, clone the
# repo, edit frequencies.bin, run tools/frequency-analyzer/, update both BLAKE3 constants
# in build.rs, and bump vsf MAJOR.

[[bin]]
name = "vsfinfo"
path = "src/bin/vsfinfo.rs"
required-features = ["text"]

# vsfimg: convert any image (PNG/JPEG/WebP/TIFF) → canonical VSF image.
# Up to 256×256 → uncompressed `Tensor<u8>` shape [h, w, 3] in VSF RGB gamma2.
# Larger → rav1e AV1 encode (matches photon's avatar encoding for >256 sources).
# ICC profile honored when present; sRGB fallback when absent.
# Provenance hash (hp) = BLAKE3 of source bytes; rolling hash (hb) = auto via VsfBuilder.
[[bin]]
name = "vsfimg"
path = "src/bin/vsfimg.rs"
required-features = ["image-tools"]

[dependencies]
bitvec = { version = "1.0.1", default-features = false, features = ["alloc"] }
chrono = { version = "0.4.38", default-features = false, features = ["alloc"] }
num-complex = { version = "0.4.5", default-features = false }
spirix = { version = "0.0.12", optional = true }
ihi = { version = "0.0.44", default-features = false, features = ["handle"], optional = true }
clap = { version = "4", features = ["derive"], optional = true }
blake3 = { version = "1", default-features = false }
ed25519-dalek = { version = "2", default-features = false, features = ["rand_core", "alloc", "zeroize"], optional = true }
x25519-dalek = { version = "2", default-features = false, features = ["static_secrets", "alloc", "zeroize"], optional = true }
rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true }
chacha20poly1305 = { version = "0.10", default-features = false, features = ["alloc"], optional = true }
aes-gcm = { version = "0.10", default-features = false, features = ["alloc", "aes"], optional = true }
hex = { version = "0.4", default-features = false, features = ["alloc"] }
i256 = { version = "0.2.3", default-features = false }
colored = { version = "2", optional = true }
num-traits = { version = "0.2.19", default-features = false, features = ["libm"] }
libm = { version = "0.2" }
spin = { version = "0.9", default-features = false, features = ["once", "rwlock"], optional = true }
# unicode-normalization: NFC canonicalization for VsfType::x. Anchored by Unicode's stability
# policy — the NFC form of an assigned codepoint is guaranteed not to change across Unicode
# versions. Same byte-determinism guarantee class as blake3/sha2/sha3 (output anchored by an
# external standard, not the dep's implementation choices). Optional + feature-gated to keep it
# off the embedded build surface.
unicode-normalization = { version = "0.1", default-features = false, optional = true }

# image-tools deps: gated behind the `image-tools` feature, only pulled in for the `vsfimg` binary.
# Versions pinned to match photon/Cargo.toml so cross-codebase pixel pipelines stay byte-identical.
image = { version = "0.25", default-features = false, features = ["jpeg", "png", "webp", "tiff"], optional = true }
img-parts = { version = "0.4", optional = true }
icc-profile = { version = "0.0.2", optional = true }
rav1e = { version = "0.7", default-features = false, optional = true }
resize = { version = "0.8.8", optional = true }
rgb = { version = "0.8.52", optional = true }

[features]
# `errors-verbose` enables `{:?}` formatting of unexpected VsfType values inside
# decode/parse error messages. Disabling drops the `core::fmt::Debug` impl for
# VsfType from the binary, which transitively drops the float-to-string code
# (~10 KB on cortex-m). Embedded callers (e.g. pipe-bridge-rp2040) build with
# `default-features = false` and don't enable it, getting static-string errors.
default = ["std", "registry", "errors-verbose"]
errors-verbose = []
std = [
    "chrono/std",
    "chrono/clock",
    "bitvec/std",
    "blake3/std",
    "hex/std",
    "num-traits/std",
    "num-complex/std",
]
# `registry` enables the global SchemaRegistry singleton (spin::Once + spin::RwLock).
# Cortex-M0+ lacks atomic CAS, which spin needs; embedded callers omit `registry` and use schema builders/parsers directly.
registry = ["dep:spin"]
crypto = ["ed25519-dalek", "x25519-dalek", "rand", "chacha20poly1305", "aes-gcm"]
spirix = ["dep:spirix"]
inspect = ["std", "registry", "dep:colored"]
text-encode = ["std", "dep:unicode-normalization"]
handle = ["dep:ihi"]
text = ["std", "registry", "dep:clap", "inspect", "text-encode", "handle"]
# image-tools: enable the vsfimg binary (image format decode + ICC + rav1e AV1 encode). Heavy deps — only pulled in when building image conversion tooling.
image-tools = [
    "std",
    "dep:clap",
    "dep:image",
    "dep:img-parts",
    "dep:icc-profile",
    "dep:rav1e",
    "dep:resize",
    "dep:rgb",
]

[build-dependencies]
# BLAKE3 for verifying frequencies.bin and huffman_codes.bin integrity at build time.
# Both files are vendored in the repo; the build fails loudly if either has been tampered
# with or regenerated without an explicit codebook bump.
blake3 = "1"

[[example]]
name = "compress_file"
required-features = ["text"]

[[example]]
name = "test_vsf_huffman"
required-features = ["text"]

[[example]]
name = "show_shortcode_colours"
required-features = ["inspect"]

[[example]]
name = "test_signing"
required-features = ["crypto"]