binrep-0.1.0: Encode binary representations via types.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Binrep.Codec

Synopsis

Documentation

class BinaryCodec a where Source #

Types that can be coded precisely between binary and a Haskell type.

This class looks identical to cereal's Serialize, but we take a different approach to instances.

Serialize defines an internal binary codec for common Haskell types. It makes implicit decisions, such as big-endian for all integer types, and coding lists with a (big-endian) Word64 length prefix. It only works with other data serialized with the same library.

This typeclass defines composable binary codec combinators. If you want to write a codec for a Word64, it needs to specify its endianness in the type. If you want to write a codec for a list with a Word8 length prefix, it must come with a proof that it's not oversized.

The idea is to use this typeclass along with various annotated newtypes to allow defining a Haskell type's binary representation directly in the types. In cases where you're doing intermediate serialization and not much else, it may be convenient. You will need to do a bunch of (free at runtime) wrapping though.

Methods

toBin Source #

Arguments

:: Putter a

Encode to binary. Same as cereal's put.

fromBin Source #

Arguments

:: Get a

Decode from binary. Same as cereal's get.

Instances

Instances details
BinaryCodec (Str 'C) Source #

Total shite parsing efficiency. But, to be fair, that's why we don't serialize arbitrary-length C strings!

Instance details

Defined in Binrep.Types.Strings

Methods

toBin :: Putter (Str 'C) Source #

fromBin :: Get (Str 'C) Source #

BinaryCodec a => BinaryCodec [a] Source #

Serialize each element in order. No length indicator, so parse until either error or EOF. Usually not what you want, but sometimes used at the "top" of binary formats.

Instance details

Defined in Binrep.Codec

Methods

toBin :: Putter [a] Source #

fromBin :: Get [a] Source #

BinaryCodec (I 'S 'I1 e) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I1 e) Source #

fromBin :: Get (I 'S 'I1 e) Source #

BinaryCodec (I 'S 'I2 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I2 'BE) Source #

fromBin :: Get (I 'S 'I2 'BE) Source #

BinaryCodec (I 'S 'I2 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I2 'LE) Source #

fromBin :: Get (I 'S 'I2 'LE) Source #

BinaryCodec (I 'S 'I4 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I4 'BE) Source #

fromBin :: Get (I 'S 'I4 'BE) Source #

BinaryCodec (I 'S 'I4 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I4 'LE) Source #

fromBin :: Get (I 'S 'I4 'LE) Source #

BinaryCodec (I 'S 'I8 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I8 'BE) Source #

fromBin :: Get (I 'S 'I8 'BE) Source #

BinaryCodec (I 'S 'I8 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'S 'I8 'LE) Source #

fromBin :: Get (I 'S 'I8 'LE) Source #

BinaryCodec (I 'U 'I1 e) Source #

Endianness doesn't apply for single-byte machine integers.

Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I1 e) Source #

fromBin :: Get (I 'U 'I1 e) Source #

BinaryCodec (I 'U 'I2 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I2 'BE) Source #

fromBin :: Get (I 'U 'I2 'BE) Source #

BinaryCodec (I 'U 'I2 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I2 'LE) Source #

fromBin :: Get (I 'U 'I2 'LE) Source #

BinaryCodec (I 'U 'I4 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I4 'BE) Source #

fromBin :: Get (I 'U 'I4 'BE) Source #

BinaryCodec (I 'U 'I4 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I4 'LE) Source #

fromBin :: Get (I 'U 'I4 'LE) Source #

BinaryCodec (I 'U 'I8 'BE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I8 'BE) Source #

fromBin :: Get (I 'U 'I8 'BE) Source #

BinaryCodec (I 'U 'I8 'LE) Source # 
Instance details

Defined in Binrep.Types.Ints

Methods

toBin :: Putter (I 'U 'I8 'LE) Source #

fromBin :: Get (I 'U 'I8 'LE) Source #

(BinaryCodec a, irep ~ IRep 'U size, itype ~ I 'U size e, Num irep, Integral irep, BinaryCodec itype) => BinaryCodec (WithRefine 'Enforced (LenPfx size e) [a]) Source #

TODO why safe

Instance details

Defined in Binrep.Types.Strings

Methods

toBin :: Putter (WithRefine 'Enforced (LenPfx size e) [a]) Source #

fromBin :: Get (WithRefine 'Enforced (LenPfx size e) [a]) Source #

(BinaryCodec a, ByteLen a, KnownNat n) => BinaryCodec (WithRefine 'Enforced (NullPadTo n) a) Source #

predicate is inherently enforced due to checking length to calculate how many succeeding nulls to parse

Note that the consumer probably doesn't care about the content of the padding, just that the data is chunked correctly. I figure we care about correctness here, so it'd be nice to know about the padding well-formedness (i.e. that it's all nulls).

Instance details

Defined in Binrep.Predicates.NullPadTo

BinaryCodec (WithRefine 'Enforced WellSized (Str ('Pascal 'I1 e))) Source #

TODO explain why safe

Instance details

Defined in Binrep.Types.Strings

binEncode :: BinaryCodec a => a -> ByteString Source #

Run the encoder for a supporting type.

binDecode :: BinaryCodec a => ByteString -> Either String a Source #

Run the decoder a supporting type.

class BinaryCodecWith r a where Source #

Types that can be coded between binary and a Haskell type given some runtime information.

We can't prove something related to a value and pass that proof along without dependent types, meaning we can't split validation from encoding like in BinaryCodec, so encoding can fail. However, by allowing an arbitrary environment, we can define many more convenient instances.

For example, you can't write a BinaryCodec instance for Word16 because it doesn't specify its endianness. But you can define 'BinaryCodecWith Endianness Word16'! This was, you can decide how much of the binary schema you want to place directly in the types, and how much to configure dynamically.

This class defaults to the free implementation provided by BinaryCodec, which ignores the environment and wraps serializing with Right.

Minimal complete definition

Nothing

Methods

toBinWith :: r -> a -> Either String Builder Source #

Encode to binary with the given environment.

default toBinWith :: BinaryCodec a => r -> a -> Either String Builder Source #

fromBinWith :: r -> Get a Source #

Decode to binary with the given environment.

default fromBinWith :: BinaryCodec a => r -> Get a Source #

Instances

Instances details
BinaryCodecWith StrRep ByteString Source # 
Instance details

Defined in Binrep.Types.Strings

BinaryCodecWith _r (Str 'C) Source # 
Instance details

Defined in Binrep.Types.Strings

Methods

toBinWith :: _r -> Str 'C -> Either String Builder Source #

fromBinWith :: _r -> Get (Str 'C) Source #

binEncodeWith :: BinaryCodecWith r a => r -> a -> Either String ByteString Source #

Run the encoder for a supporting type using the given environment.

binDecodeWith :: BinaryCodecWith r a => r -> ByteString -> Either String a Source #

Run the decoder for a supporting type using the given environment.