2 min read

Rust crate brings lawful numeric casts to Galois connections

A new Rust crate turns Galois connections into composable, property-tested casts with compile-time guarantees and Rust 1.88 as its MSRV.

Image: Hacker News

A new Rust crate called connections packages Galois connections as first-class Rust values for lawful, composable numeric casts. The project is a Rust-native port of the Haskell library connections, with an MSRV of Rust 1.88 and a promise that future MSRV bumps will be released as minor-version changes rather than patch-level breakage.

The pitch is straightforward: Rust’s standard cast tools such as as, From, and Into only express one direction at a time, while as can hide rounding, saturation, and lossy conversion behavior. connections instead models a conversion as a paired relationship with explicit rules. The crate says every operation derived from a Conn — including rounding, saturation, and median — carries a property-tested invariant.

One example in the docs contrasts Rust’s built-in cast behavior with an explicit saturating connection:

  • u32::MAX as i32 yields -1
  • U032I032.floor(u32::MAX) yields i32::MAX
  • U032I032.lower(-1) yields 0_u32

A Conn is described as Copy, const-constructible, heap-free, and built under #![forbid(unsafe_code)]. The crate also includes a compose! macro that combines pairwise connections into a fresh Conn<Src, Dst> at compile time, preserving the same laws across the full chain by construction.

The implementation is unusually heavy on formal verification. The generated fixed-width integer, Q-format, NonZero, and iso families include Kani harnesses for full bit-width SMT proofs, while the project notes that float SMT coverage is narrower. The crate also exposes separate L-kind and R-kind connections, with APIs like .ceil() and .upper() on one side, and .floor() and .lower() on the other, so invalid combinations fail at compile time.

Recommended reading

Samsung 990 SSD hits 7,250 MB/s with a 2TB option

The module list is broad. Beyond integer and float conversions, it covers std::time::Duration, the time crate, hifitime, uhlc, std::net address conversions, char codepoint projection, pointer-width casts, and sortable byte encodings.

For Rust developers dealing with multi-step conversions such as f64 → f32, Duration → seconds, or even f32 → u32 → IpAddr, the project’s core claim is that round-trip behavior should follow simple inequalities, not whatever happens to fall out of chained casts.

Tomas Berg

Computing Editor

Tomas lives in the terminal. He covers chips, laptops, and operating systems with a focus on performance and efficiency. He reads kernel changelogs the way other people read fiction, and he's always on the hunt for the perfect mechanical keyboard switch. If it processes data, Tomas has an opinion on it.

via Hacker News

// Keep reading