Repository navigation
v0.3.0 - what the first consumer asked for
The first real consumer to route an entire scalar-parser family through a HyperCast binding was Svartalfheim's ingestion branch (NorseArchitecture/Svartalfheim#62). Read against this repo, that one PR surfaced every gap this release closes: a declared currency symbol, without which every non-invariant culture fell back to managed code; an exact decimal door; a way to prove the native library loaded before the first cast; and a handful of binding ergonomics. It is one coordinated ABI bump across the core and all seven bindings. docs/roadmap.md records the reasoning; CHANGELOG.md is the rdocs/roadmap.md records the reasoning; CHANGELOG.md is the rThis release also carries the wasm backends for Java, Ruby, Pythn Unreleased: the core as a wasm32-wasip1 module runningin-process through an engine each ecosystem already has, behind nd switch, opt-in and dependency-free until asked for.## The core- A declared currency symbol on NumFormat, up to 16 UTF-8 URRENCYflag that joinsALL. Accepted once at either edge ofthe numeric body — leading before or after a sign ($5, -$5, 1.234,50 kr.) — with accounting parentheses wrapping symbol anddigits together (($5)). Declared with the flag off, the symboly character; flag on with nothing declared changes nothing.- cast_decimal — the real doors' grammar to an exact sign, scale. No float is ever formed: 0.1 is one tenth and 50% isexactly 0.5. The result is canonical — trailing fraction zeros come out the same, and zero is scale 0, never negative. Nothingbut a zero is ever dropped: excess nonzero precision is OutOfRa- **hypercast_version** — a zero-argument export returning theor << 16 | minor << 8 | patch. The cheapest possible proof thatthe library a host loaded is the one its binding was built again- RawNumFormat is 32 bytes. corpus/decimal.json is new; intined currency vectors. The fuzz target, the counting-allocatorproof and the fault-span sweep cover all of it.## Every binding- The 32-byte format crossing on every backend, native and wasm.- The decimal door mapped to the platform's exact type — decima decimal.Decimal (Python), Foundation.Decimal (Swift) — or anexact carrier where there is none: Go Decimal through the Exacimal with to_r, canonical to_s and a lazily required to_d,PHP HyperCast\Decimal with the magnitude as a numeric string.- The currency symbol filled in from the platform's own locale dnfo), NumFormat.from(Locale), NumFormat.from(locale:),from_localeconv, fromLocaleconv.- An availability probe that never throws, and the loaded core'silable/NativeVersion, Cast.isAvailable()/nativeVersion(),Available()/NativeVersion(), Cast.isAvailable/nativeVersi/native_version, hypercast.native_version(),Cast::isAvailable()/nativeVersion(). A consumer keeping a marobe instead of catching a load failure around its first realcast.## Binding ergonomics, ported system-wideEach began as a C# finding and was carried to every binding wheric home for it:- **One numeric door generic over the target** — C# Cast.Numeri numeric targets, Go Numeric[V Number] with the eleven as aconstraint, Swift Cast.numeric<T> closed over a NumericCastTano generics over primitives) nor the dynamic bindings, where theper-width doors are the idiom.- **Fault spans in the caller's own units** — the core reports Uring doors, Java String doors, Python str and Ruby textinputs now remap to char or code-point units on a non-ASCII fail text out of what was passed needs no mapping. Byte input andASCII text are untouched. Go, Swift and PHP strings are already- The culture bridge in the shape the platform already uses ider)andFrom(NumberFormatInfo) in C#,NumFormat::fromLocaleconv() in PHP.## Receipts- **HyperCast.Corpuson NuGet** — the conformance corpus as a ed in lockstep withHyperCast, packed, attested and pushed bythe same release run. NuGet only, on purpose: the corpus is a rems' receipts are their own suites replaying it.- **Benchmarks recorded as measured.** In the core, cast_decima cast_f64 on the same text (30.5 vs 28.1 ns) and 58.8 ns with adeclared symbol and grouping. In C#, Cast.Decimal is a wash ag9 vs 94.8 ns) and the currency path is a 1.6–1.7x loss againstNumberStyles.Currency on both the decimal and double doors. Thncy path is isolated in docs/roadmap.md as the nextoptimization; what the loss buys is the reason it was asked for.- Every suite green on a fresh build: Rust native and under was AOT publish with zero trim diagnostics; Java native and GraalWasmplus a GraalVM Native Image smoke; Go on cgo, purego and wasmtimdle and wasm; Python native and wasm; PHP.## Upgrade notesSource-compatible for every binding's consumers, with three thin- **The native library and the binding move together.** A 0.3.0 cast fails at load, which the new probe reports rather than thefirst cast.- ALL changed value (95, from 31): code that stored the nuet; code that named the constant gains currency, which with nosymbol declared changes nothing. SEPARATOR_DETECT stays exclud- Non-ASCII fault spans on the C#, Java, Python and Ruby text ot bytes. The byte doors are untouched.Two source-level changes for direct users of the crate and the J struct literal of the three old fields no longer compiles — useNumFormat::new(decimal_sep, group_sep, flags)or{ ..NumFormaormatis a four-component record withcurrencySymbol` last, andthe three-argument constructor remains.
The wasm backends are opt-in and change nothing until asked for: any package.