Skip to content

v0.7.0 - interop, numbers already held, faster, and iOS

Choose a tag to compare

@buvinghausen buvinghausen released this 07 Oct 03:07
· 101 commits to master since this release
03aec55

0.7.0 is shaped by the libraries that build on HyperCast: HyperTabular and HyperWorkbook. It also adds one new platform family: C#, Swift and Go now link the core into iOS and Mac Catalyst apps, as HyperUuid's 0.7.0 does. The manifests read 0.6.2 between releases, but no 0.6.2 was ever published, so everything since 0.6.1 is here. The full list is in CHANGELOG.md.

Highlights

  • iOS and Mac Catalyst, in C#, Swift and Go. Those platforms load no libraries, so the core is linked into the app from static archives built and attested in the same CI job as everything else.

    Language How
    C# A .NET iOS, MAUI or Mac Catalyst app (net11.0-ios, net11.0-maccatalyst) references the package and writes nothing else. It covers ios-arm64, iossimulator-arm64, maccatalyst-arm64 and maccatalyst-x64.
    Swift iOS 16, the iOS simulator and Mac Catalyst 16 on arm64, linked from a new HyperCastCoreApple.xcframework. Linux, Windows and WebAssembly builds see the same package as before.
    Go cgo builds for an iOS device, the iOS simulator on Apple silicon (-tags iossimulator) and Mac Catalyst on either architecture (-tags maccatalyst, which gomobile sets).

    CI tests each one on a Mac on every PR: the suites run in an iOS simulator and as a Mac Catalyst process, and builds for a real iOS device are checked to contain the core. Android, tvOS and the Intel iOS simulator remain unsupported.

  • Interop: a public surface for libraries that carry HyperCast's results across a C ABI of their own. Every binding now exposes the code that turns the core's raw out-values, numeric format, reason codes and fault spans into its own types. The doors use exactly that code, so a value read out of another library's buffer is the value the door would have returned. HyperTabular no longer copies private code.

    • C#: HyperCast.Interop
    • Java: io.github.skunkwerkx.hypercast.interop
    • Swift: Interop
    • PHP: HyperCast\Interop
    • Ruby: HyperCast::Interop
    • Go: the Raw* types and *FromCode functions
    • Python: NumFormat.packed
    • Rust: from_code on the enums, a public RawNumFormat, and a python-values feature
    • Rust's C symbols are now an exports feature, so a crate that exports its own C ABI can turn them off.
  • Numbers already held. A workbook stores a numeric cell as a double, not text. Four new doors read that f64 directly as:

    • an exact decimal
    • an Excel serial
    • a time of day
    • a span

    That takes the C ABI to 25 cast_* exports plus hypercast_version, and every binding has them. Rust also gains the whole typed family (i32_from_f64 … excel_duration).

    • The double is read as the number it names: 2.5 is 2.5, the digits Excel and LibreOffice wrote into the file.
    • Times read back exactly: Excel's and Google's serials snap to the time the writer stored, instead of drifting into float noise.
  • Faster. Rust figures on linux-x64:

    • The temporal doors are about twice as fast: cast_timestamp 26.6 → 14.5 ns, cast_datetime 29.3 → 13.9 ns, cast_duration 35.5 → 23.6 ns.
    • cast_f64 and cast_f32 are 22-36% faster.
    • cast_uuid is about 20% faster.

    Bindings that cross cheaply keep most of it. In Swift, duration went from 45 to 33 ns. C#'s Cast.Duration went from 49.1 to 31.6 ns. The shared library grows about 10 KB for the inlining.

  • Every door is now proven unable to panic. cast_f32 and cast_f64 were the last two outside the link-time proof. Their float conversion is now HyperCast's own code and gives the same bits as core's parser, checked over about 1.5 million generated inputs. All 26 exports are in the proof on every PR.

Upgrade notes

Source-compatible for almost every consumer. The first item is the only one most will meet.

  • Every package: a fraction of a second past nine digits now succeeds, truncated to the nanosecond. 15:04:05.0000000001 was Malformed. ISO 8601, RFC 3339 and XSD put no cap on fraction digits, and Excel writes seventeen. Code that relied on the refusal must check the text itself.
  • Rust: a default-features = false build no longer carries the C ABI symbols. Name exports beside std if you relied on them. Default builds are unchanged.
  • PHP: HyperCast\NativePlatform (always @internal) is now HyperCast\Interop\NativePlatform, and its methods take the library's base name first.
  • Java: CastFailure.fromCode is public and returns Optional<CastFailure> instead of throwing. It was package-private before.
  • Go: GOOS=android no longer compiles. It used to link the untested Linux archive. If you need Android, open an issue.

Verifying

Every native library and static archive in this release is built by CI and carries a build-provenance attestation, the new iOS and Mac Catalyst archives included:

gh attestation verify go/staticlib/linux_amd64/libhypercast.a \
  --repo SkunkWerkx/HyperCast --signer-repo SkunkWerkx/.github

The gems and Python wheels are attested by this repo's own release.yml, so --repo SkunkWerkx/HyperCast alone verifies them