HyperCast 0.0.2
dotnet add package HyperCast --version 0.0.2
NuGet\Install-Package HyperCast -Version 0.0.2
<PackageReference Include="HyperCast" Version="0.0.2" />
<PackageVersion Include="HyperCast" Version="0.0.2" />
<PackageReference Include="HyperCast" />
paket add HyperCast --version 0.0.2
#r "nuget: HyperCast, 0.0.2"
#:package HyperCast@0.0.2
#addin nuget:?package=HyperCast&version=0.0.2
#tool nuget:?package=HyperCast&version=0.0.2
HyperCast
TryParse hands back a bool and a shrug. These doors hand back a native discriminated
union — the value, or Empty/Malformed/OutOfRange plus the exact byte span that
offended — and an unhandled case is a compile error, not a review nit.
Allocation-free scalar casts — booleans, the full integer family, reals, UUIDs, temporals —
as source-generated [LibraryImport] P/Invoke straight into the native libhypercast Rust
core. No runtime bridge, no reflection anywhere in the assembly. .NET 11 is the floor
deliberately: Verdict<T> is a real [Union], and CS8509 (non-exhaustive switch) is
elevated to an error, so a missing disposition fails the build — the entire point of
returning a union instead of throwing.
var message = Cast.Int32("(1,234)", NumFormat.From(culture)) switch
{
Success<int> s => $"got {s.Value}", // -1234, accounting negative
Fault f => $"{f.Reason} at byte {f.Offset}", // no third case: the compiler checked
};
Door names mirror the native ABI (Int32, Double, Timestamp, …) so the polyglot
surface reads identically across bindings. Culture never lives in the core —
NumFormat.From(CultureInfo) bridges .NET's culture machinery to the caller-declared
format the native side actually reads. .NET-flavored fidelity, stated honestly:
DateTimeOffset/TimeOnly/TimeSpan resolve to 100 ns ticks, so sub-tick nanoseconds
truncate (the core carries full nanosecond fidelity; .NET's clock types don't).
Why not the BCL's own TryParse family?
The error story is data, not archaeology — a closed reason plus the offending span, against the BCL's bare
false.The vocabulary untrusted sources actually send — twenty boolean lexemes, accounting parentheses, radix prefixes, all five
Guidformats plusurn:uuid:prefixes, protobuf JSON durations — much of it grammar the BCL has no knob for at any price.One engine across a polyglot system — the same Rust core, bit-for-bit verdicts, proven by the shared conformance corpus every binding replays (all 28 of this binding's tests include the full twelve-file corpus through real P/Invoke).
Not slower — mostly faster. BenchmarkDotNet,
[MemoryDiagnoser], lenience matched where the BCL has the knob, FFI crossing and UTF-16→UTF-8 transcode included in every HyperCast number; zero managed allocation on every row, both sides (linux-arm64, .NET 11 preview):Door HyperCast BCL Verdict Cast.TimestampvsDateTimeOffset.TryParse71.0 ns 285.6 ns 4.0x faster Cast.DurationvsTimeSpan.TryParse64.1 ns 143.0 ns 2.2x faster Cast.Doublevsdouble.TryParse50.4 ns 69.8 ns 1.4x faster Cast.UuidvsGuid.TryParse54.8 ns 51.9 ns wash — while also taking N/B/P/X and urn:uuid:Cast.Int32(grouped) vsint.TryParse64.5 ns 54.0 ns 1.2x slower — the crossing tax, paid honestly Cast.Booleanvsbool.TryParse18.5 ns JIT-folded honest loss — the twenty-lexeme vocabulary is why anyone calls this door Cast.DateTime(1/7/2026 3:04 PM) vsDateTime.TryParse(en-US)61.2 ns 222.9 ns 3.6x faster Cast.Date(declared order) vsDateOnly.TryParse(en-US)33.7 ns 132.3 ns 3.9x faster Cast.Double(eurozone) vsdouble.TryParse(de-DE)98.7 ns 65.9 ns 1.5x slower — see below Reproduce:
dotnet run -c Release --project HyperCast.Benchmarks.Separator detection is nearly free:
NumFormat.Detecton1.234.567,89costs 104.4 ns against 98.7 ns for the same text under a declared eurozone format — ~6 ns for resolving the./,roles structurally instead of being told them.
The honest trade-off: the eurozone double row is a real loss — double.TryParse
under de-DE beats this door by ~33 ns, because non-invariant separators take the door's
normalize-then-parse path rather than its invariant fast lane. And it's a native dependency
(shipped per-RID inside the package) with a ~15–65 ns FFI crossing on every call. For plain
invariant integers the BCL is already excellent; these doors earn their keep on the
culture-machinery parsers, the closed error contract, and cross-language agreement.
AOT
IsAotCompatible is asserted and the analyzers fail the build on violations; the
HyperCast.AotSmokeTest project publishes under PublishAot into a genuine native binary
that runs every door — proven, not configured.
WebAssembly (Blazor)
One compiled assembly covers browser-wasm too — every native entry point is declared twice
("hypercast" for dlopen platforms, "*" for the statically-linked wasm module), sharing
the same EntryPoint, with OperatingSystem.IsBrowser() picked at the call site and
constant-folded by the linker. CI builds the wasm32-unknown-emscripten staticlib on every
PR; the release pack stages it under runtimes/browser-wasm/nativeassets/, and
build/net11.0/HyperCast.targets ships inside the package to wire it up for a consumer with
no configuration at all.
That targets file is load-bearing, and both halves of it are: a NativeFileReference hands
the staticlib to the linker (restore never populates @(NativeLibrary) from a plain
PackageReference's nativeassets/ folder the way it does runtimes/{rid}/native/), and an
EmccExportedFunction per door makes the linked-in symbols resolvable through
LibraryImport("*") at runtime — the WASM SDK exports only its own baseline set and never
scans P/Invoke declarations to find the rest. v0.0.1 shipped without that file, and a real
Blazor consumer's publish died at wasm-ld with undefined symbol: cast_i32.
Install
dotnet add package HyperCast
Per-RID native libraries ship inside the package under runtimes/, so a consumer adds one
reference and nothing else — no build step, no manual native staging.
See the repo root README for the full door table, the receipts, and the state of every other language binding.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net11.0 is compatible. |
-
net11.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.