| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
Binrep
Description
Top-level binrep module, exporting all classes, generics & runners.
binrep helps you precisely model binary schemas by combining simple "building
blocks" (e.g. ) in regular
Haskell types. You can then receive high-performance serializers and parsers for
free via generics.NullTerminated a
binrep is not a general-purpose parsing/serializing library. For that, see
- mason, for fast and flexible serializing
- flatparse, for extremely performant parsing
- bytezap, for overly-fast serializing and parsing (but very limited)
Synopsis
- module Binrep.BLen
- module Binrep.CBLen
- module Binrep.Put
- module Binrep.Put.Struct
- module Binrep.Get
- module Binrep.Get.Struct
Class and instance design
At the core of binrep are a set of classes defining parsers, serializers, and serialized length checkers on supported types. binrep is its own ecosystem where explicitness and correctness win over all:
- there are no binrep instances for
VoidorV1because we can't use them; rather than providing an absurd, possibly convenient instance, we emit a type error for their attempted use. - you can't put/get
Word32s etc by themselves; you must provide endianness information via theByteOrderednewtype just consumes the whole input. seem weird? it works with the combinators (it's actually rather important)GetByteString
Here are some important design decisions:
- Fields in product types are concatenated left-to-right. e.g.
first putsPut(l, r)l, thenr. Nothing is placed between them. - Sum types must define how to handle the constructor sum.
Generics are split into sum handlers and non-sum handlers.
binrep instances are not provided for types such as
, where we can't state how to choose between theEithera bLeftandRightconstructors. is re-associated toRefined(plAndpr) a. The single layer of refinements is ergonomic, but the way binrep instances work means we need the latter. SoRefinedpr (Refinedpl a)Andinstances essentially rewrite themselves to work as if it were a stack of refinements. (SeeNullTermPaddedfor an example.)
Struct parsing & serializing
There are experimental "struct" handlers, which only work on data types that look like C structs. That is,
- every field must be constant length, and
- no sums allowed.
The underlying runners for these are even faster-- they shouldn't do much more
work than the code a C compiler would generate for a similar struct. But they
are very inflexible (few binrep instances, hard to write by hand) and poorly
tested. Please be warned when using them. (And do consider sending bug reports
to the author!)
module Binrep.BLen
module Binrep.CBLen
module Binrep.Put
module Binrep.Put.Struct
module Binrep.Get
module Binrep.Get.Struct