Skip to content

Releases: sothis/bovnar

v1.1.0

21 Jun 08:19

Choose a tag to compare

Bovnar 1.1.0 — native time, opt-in and fully compatible

Spec 1.1 adds a native time family to the unit-safe format — and nothing
else changes.
Every 1.0 document parses unchanged and decodes to the same
values; the new constructs are opt-in, enabled per document by a leading
#!bovnar 1.1 directive. A 1.0 reader skips the directive as a comment, and a
1.1 reader treats a directive-less document as spec 1.0.

#!bovnar 1.1
.launch  = <datetime:64,tai> 2026-05-28T00:00:00Z;  # epoch-aware timestamp
.created = 2026-06-15T12:00:00.5Z;                   # bare ISO literal → <datetime:64,unix>
.label   = "caf\u{e9}";                              # \u{…} / \xHH string escapes
.cell    = &.matrix[0][1];                           # references can index arrays

This is an additive 1.x release: per the §17 stability contract, it only
adds new constructs, appends new error codes after the previous maximum, and
adds optional reader/writer flags. No 1.0 document is invalidated — with one
reserved-prefix exception: because #!bovnar on a first-line comment is now a
version directive, a 1.0 document whose first line is a comment beginning
literally with #!bovnar followed by non-version text is now reported as a
malformed directive rather than skipped. #!bovnar was never a 1.0 convention,
so no realistic document is affected.

Install

pip install --upgrade bovnar     # pure-ctypes bindings + bundled shared library

Binary wheels are published for CPython 3.10–3.14 on Linux (x86_64,
aarch64) and macOS (arm64, x86_64); an sdist is available for other targets.

C / embedding: vendor the single-file amalgamation dist/bovnar.h +
dist/bovnar.c (C99, no dependencies), or build the library with CMake. The
build understands the highest spec it supports via bvnr_spec_version() /
BVNR_SPEC_VERSION_MAJOR·MINOR (now 1·1).

Windows: the library and CLI now build natively on 64-bit Windows with both
MinGW64 and MSVC — see Windows build support below.

What's new in 1.1

  • Version directive — an optional first-line #!bovnar <major>.<minor>
    comment declaring the spec a document targets. A 1.1 reader records it
    (bvnr_reader_get_declared_version, the bovnar version CLI) and, with the
    strict_version read flag, rejects a version it does not support.
  • Native time family<datetime:width,epoch> carries a timestamp as a
    signed integer count of seconds since a named epoch (unix default, plus
    tai, gps, mjd, ntp, galileo, glonass, y2000, beidou) — distinct
    from a duration (a number with a time unit). The epoch is recoverable
    (bvnr_datetime_epoch_name/_mjd) and convertible to civil time via
    bvn_datetime.h. In an array, datetime is its own kind and its epoch is a
    dimension.
  • ISO-8601 datetime literals — write YYYY-MM-DD or
    YYYY-MM-DDTHH:MM:SS, with an optional Z, a numeric ±HH:MM offset, and/or
    a fractional second, instead of a raw integer. It converts to the epoch-seconds
    carrier at parse time and round-trips idempotently; a bare literal infers
    <datetime:64,unix>. The UTC→epoch conversion is leap-second correct
    (tai applies the IERS table); the atomic GNSS epochs reject a literal, since
    they have no round-trippable civil⇄seconds inverse — use an integer carrier
    there. A fractional second is preserved verbatim and re-emitted as an ISO
    literal.
  • Richer string escapes\u{1–6 hex} (a Unicode scalar, UTF-8 encoded)
    and \xHH (one byte), both held to the same valid-UTF-8 / no-raw-control rules
    as the rest of the string grammar.
  • Reference array indexing — a reference path may index arrays,
    &.matrix[0][1], resolved by bvn_dom_lookup (and bovnar query).
  • Python & numpybovnar.version()/spec_version()/peek_version(),
    Reader.declared_version, Quantity.epoch_name/epoch_mjd,
    ValueTypeFamily.DATETIME. dumps() auto-prepends #!bovnar 1.1 (and the
    <datetime> annotation) only when the value tree needs it, so typed
    round-trips stay lossless. The numpy bridge maps a unix-epoch datetime array
    to/from datetime64[s].
  • Python — lossless wide/decimal/fixed-point floatsQuantity gains
    .decimal()/.fraction() (the exact value from the verbatim literal) and
    .stored_value()/.ieee_bits()/.fixed_point() (bit-exact materialisation of
    the 16/32/64/128/256 encodings), plus a from_number constructor; dumps()
    accepts Decimal/Fraction. The numpy bridge decodes float_dec/float_fix/
    float:128+ to exact Decimal object arrays (with from_numpy(float_format=)
    to write them), and the arbitrary-precision bvn_float API is exposed as
    bovnar.BvnFloat.
  • Windows build support (64-bit MinGW64 and MSVC) — the library (bvnr.dll
    plus import lib and a static archive) and the bovnar CLI now build natively
    on Windows. A portability shim (src/utils/bvn_port.h) maps the fd I/O onto the
    CRT and — critically for a binary format — forces binary mode on files and on
    stdin/stdout/stderr so no CRLF translation can corrupt the byte stream. On MSVC
    the static archive is bvnr_static.lib (the DLL import lib takes bvnr.lib);
    MinGW keeps the unified libbvnr names. A new Build & Package CI workflow
    builds both Windows toolchains and a native Linux target, smoke-tests the CLI,
    and publishes the build + amalgamation artifacts.
  • Tooling — a bovnar version subcommand; the datetime keyword in all five
    syntax highlighters and the web playground; and a conformance suite grown to
    306 cases (up from 207), adding the version and datetime groups —
    including the ISO-literal DTLIT cases — passing in both self-test and --iut
    modes.

New error codes (appended, non-breaking)

error_invalid_spec_version (42), error_unsupported_spec_version (43),
error_invalid_codepoint (44), error_invalid_datetime_literal (45),
error_datetime_literal_unsupported_epoch (46). Existing codes are unchanged.

Compatibility

  • 1.0 documents are unaffected — parse unchanged, decode identically. The
    1.0 freeze (grammar, type families, arrays/structs/octet-streams/references,
    homogeneity rules, error-code values) still holds.
  • 1.1 constructs are opt-in — they require the #!bovnar 1.1 directive; a
    1.1-only construct in a directive-less (spec-1.0) document is an error, exactly
    as a 1.0 reader reports.

Documentation

Full docs — tutorial, specification, unit/currency reference, C and Python API,
formal EBNF grammar, FAQ, conformance protocol, and cheat sheet — are available
at https://www.bovnar.io (each also downloadable as PDF), and in the
doc/ directory. See
CHANGELOG.md for the complete change list.

License

MIT.

Bovnar 1.0.0 — first stable release

01 Jun 15:10

Choose a tag to compare

Bovnar 1.0.0 — first stable release

Unit-safe serialization for science, industry, and finance. Every value in a
.bvnr document carries its type family, bit-width, numeric base, and a
validated physical unit or currency — inline, in the same byte stream, with
no external schema. A bare 9.81 is never ambiguous, and a mismatched unit is a
parse error.

.thrust   = <float:64,k~N> 7.6;       # 7.6 kilonewtons
.altitude = <uint:32,m>    412000;    # 412 km, explicit width + unit
.price    = <float_dec:64,$USD> 19.99;
.matrix   = [1, 2, 3]/[4, 5, 6];      # rectangular, homogeneous

This is the 1.0 format freeze: a document valid under spec 1.0 stays valid,
and decodes to the same values, under every 1.x release.

Install

pip install bovnar          # pure-ctypes bindings + bundled shared library

Binary wheels are published for CPython 3.10–3.14 on Linux (x86_64,
aarch64) and macOS (arm64, x86_64); an sdist is available for other targets.

C / embedding: vendor the single-file amalgamation dist/bovnar.h +
dist/bovnar.c (C99, no dependencies), or build the library with CMake.

Highlights

  • Self-describing, unit-safe values — type family (uint/sint/float/
    float_fix/float_dec/utf8/bool), bit-width, numeric base, and unit all
    travel with the value and are validated by the parser.
  • Rich unit system — 163 named physical units, SI/IEC prefixes, and compound
    expressions (k~g/(m·s²)), plus 164 ISO 4217 fiat currencies and 50
    cryptocurrencies
    with minor-unit metadata.
  • First-class structure — nested structs, multi-dimensional arrays with a
    clean /-row syntax, references, and native binary embedding via octet streams
    (no Base64).
  • Streaming C API and pure-ctypes Python bindings (loads/dumps plus
    event-driven Reader/Writer), with optional pint and numpy bridges.
  • bovnar CLI — validate, query by path, pretty-print, convert to/from JSON,
    inspect the event stream, and benchmark.
  • Tooling — registered media type text/vnd.bovnar (+ .bvnr), syntax
    highlighters (VS Code, Sublime, Vim, Geany), and a 207-case conformance suite
    with an IUT protocol for verifying third-party implementations.

Breaking changes (the 1.0 freeze — finalized before this line)

These tightened the format and cannot change within 1.x:

  • Currencies require a mandatory $ sigil ($USD, $BTC), so a currency
    code can never collide with a physical-unit symbol.
  • Special floats are bare keywordsnan, inf, ninf (the previous
    $-sigil form was removed).
  • Array elements must be homogeneous — same kind and dimension; sibling
    sub-arrays must be rectangular. Heterogeneous/ragged data uses a struct.
  • float_fix values are range-validated against the declared Q-format
    (out-of-range is error_value_out_of_range).

Stability contract (spec §17)

  • Frozen at 1.0: the grammar, type families and annotations, arrays/structs/
    octet-streams/references, the homogeneity rules, and the error-code values.
  • Additive in 1.x (non-breaking): new units/prefixes/currencies, new error
    codes appended after the current maximum, and new optional reader/writer flags.
  • Reserved for 2.0: anything that could invalidate a 1.x document, change how
    it decodes, renumber an error code, or alter the grammar.

Documentation

Full docs — tutorial, specification, unit/currency reference, C and Python API,
formal EBNF grammar, FAQ, conformance protocol, and cheat sheet — are available
at https://www.bovnar.io (each also downloadable as PDF), and in the
doc/ directory.

License

MIT.