-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Encode binary representations via types. -- -- Please see README.md. @package binrep @version 0.1.0 module Binrep.ByteLen -- | The size in bytes of the type can be known, preferably on the cheap -- e.g. reading a length field. -- -- Aim to make this O(1). Except for where you can't like lists lol. -- -- Importantly goes hand in hand with BinaryCodec! Maybe we should make -- it a function there lol! -- -- This is useful for padding types generically, without having to track -- the read/write cursor. Yes, that feature *is* common and cheap for -- parsers (and to lesser extent, serializers), but you should really -- only be padding types that have a "static-ish" (= cheaply calculated) -- size. At least, I think so? I'm not quite sure. -- -- Some instances ignore the argument. It would be possible to pull those -- out into a statically-known bytelength typeclass, but it wouldn't -- improve clarity or performance, just get rid of a couple -- undefineds. class ByteLen a blen :: ByteLen a => a -> Natural instance Binrep.ByteLen.ByteLen a => Binrep.ByteLen.ByteLen [a] module Binrep.Codec -- | 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. class BinaryCodec a toBin :: BinaryCodec a => Putter a fromBin :: BinaryCodec a => Get a -- | Run the encoder for a supporting type. binEncode :: BinaryCodec a => a -> ByteString -- | Run the decoder a supporting type. binDecode :: BinaryCodec a => ByteString -> Either String a -- | 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. class BinaryCodecWith r a -- | Encode to binary with the given environment. toBinWith :: BinaryCodecWith r a => r -> a -> Either String Builder -- | Encode to binary with the given environment. toBinWith :: (BinaryCodecWith r a, BinaryCodec a) => r -> a -> Either String Builder -- | Decode to binary with the given environment. fromBinWith :: BinaryCodecWith r a => r -> Get a -- | Decode to binary with the given environment. fromBinWith :: (BinaryCodecWith r a, BinaryCodec a) => r -> Get a -- | Run the encoder for a supporting type using the given environment. binEncodeWith :: BinaryCodecWith r a => r -> a -> Either String ByteString -- | Run the decoder for a supporting type using the given environment. binDecodeWith :: BinaryCodecWith r a => r -> ByteString -> Either String a instance Binrep.Codec.BinaryCodec a => Binrep.Codec.BinaryCodec [a] module Binrep.Types.Ints -- | Wrapper type grouping machine integers (sign, size) along with an -- explicit endianness. newtype I (sign :: ISign) (size :: ISize) (e :: Endianness) I :: IRep sign size -> I (sign :: ISign) (size :: ISize) (e :: Endianness) [getI] :: I (sign :: ISign) (size :: ISize) (e :: Endianness) -> IRep sign size -- | Byte order. data Endianness -- | big endian, MSB first. e.g. most network protocols BE :: Endianness -- | little endian, MSB last. e.g. most processor architectures LE :: Endianness -- | Machine integer sign data ISign -- | signed S :: ISign -- | unsigned U :: ISign -- | Machine integer size in number of bytes. data ISize I1 :: ISize I2 :: ISize I4 :: ISize I8 :: ISize type family IRep (sign :: ISign) (size :: ISize) instance GHC.Generics.Generic (Binrep.Types.Ints.I sign size e) instance GHC.Show.Show (Binrep.Types.Ints.IRep sign size) => GHC.Show.Show (Binrep.Types.Ints.I sign size e) instance GHC.Classes.Eq (Binrep.Types.Ints.IRep sign size) => GHC.Classes.Eq (Binrep.Types.Ints.I sign size e) instance GHC.Classes.Ord (Binrep.Types.Ints.IRep sign size) => GHC.Classes.Ord (Binrep.Types.Ints.I sign size e) instance GHC.Enum.Bounded (Binrep.Types.Ints.IRep sign size) => GHC.Enum.Bounded (Binrep.Types.Ints.I sign size e) instance GHC.Num.Num (Binrep.Types.Ints.IRep sign size) => GHC.Num.Num (Binrep.Types.Ints.I sign size e) instance GHC.Real.Real (Binrep.Types.Ints.IRep sign size) => GHC.Real.Real (Binrep.Types.Ints.I sign size e) instance GHC.Enum.Enum (Binrep.Types.Ints.IRep sign size) => GHC.Enum.Enum (Binrep.Types.Ints.I sign size e) instance GHC.Real.Integral (Binrep.Types.Ints.IRep sign size) => GHC.Real.Integral (Binrep.Types.Ints.I sign size e) instance Data.Aeson.Types.ToJSON.ToJSON (Binrep.Types.Ints.IRep sign size) => Data.Aeson.Types.ToJSON.ToJSON (Binrep.Types.Ints.I sign size e) instance Data.Aeson.Types.FromJSON.FromJSON (Binrep.Types.Ints.IRep sign size) => Data.Aeson.Types.FromJSON.FromJSON (Binrep.Types.Ints.I sign size e) instance Binrep.ByteLen.ByteLen (Binrep.Types.Ints.I s 'Binrep.Types.Ints.I1 e) instance Binrep.ByteLen.ByteLen (Binrep.Types.Ints.I s 'Binrep.Types.Ints.I2 e) instance Binrep.ByteLen.ByteLen (Binrep.Types.Ints.I s 'Binrep.Types.Ints.I4 e) instance Binrep.ByteLen.ByteLen (Binrep.Types.Ints.I s 'Binrep.Types.Ints.I8 e) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I1 e) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I1 e) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I2 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I2 'Binrep.Types.Ints.LE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I2 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I2 'Binrep.Types.Ints.LE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I4 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I4 'Binrep.Types.Ints.LE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I4 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I4 'Binrep.Types.Ints.LE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I8 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.U 'Binrep.Types.Ints.I8 'Binrep.Types.Ints.LE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I8 'Binrep.Types.Ints.BE) instance Binrep.Codec.BinaryCodec (Binrep.Types.Ints.I 'Binrep.Types.Ints.S 'Binrep.Types.Ints.I8 'Binrep.Types.Ints.LE) module Binrep.Util tshow :: Show a => a -> Text module Binrep.Types.Strings -- | TODO data StrRep C :: StrRep Pascal :: ISize -> Endianness -> StrRep -- | TODO -- -- We also use this as a predicate, because the Pascal constructor -- looks identical to what we would want for a LengthPrefixed -- predicate. newtype Str (rep :: StrRep) Str :: ByteString -> Str (rep :: StrRep) [getStr] :: Str (rep :: StrRep) -> ByteString fromBinCString :: Get ByteString data WellSized type LenPfx size e = Str ('Pascal size e) instance (Binrep.ByteLen.ByteLen a, itype GHC.Types.~ Binrep.Types.Ints.I 'Binrep.Types.Ints.U size e, Binrep.ByteLen.ByteLen itype) => Binrep.ByteLen.ByteLen (Refined.WithRefine.WithRefine 'Refined.WithRefine.Enforced (Binrep.Types.Strings.LenPfx size e) a) instance (Data.Foldable.Foldable f, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable e) => Refined.Predicate (Binrep.Types.Strings.LenPfx 'Binrep.Types.Ints.I4 e) (f a) instance (Binrep.Codec.BinaryCodec a, irep GHC.Types.~ Binrep.Types.Ints.IRep 'Binrep.Types.Ints.U size, itype GHC.Types.~ Binrep.Types.Ints.I 'Binrep.Types.Ints.U size e, GHC.Num.Num irep, GHC.Real.Integral irep, Binrep.Codec.BinaryCodec itype) => Binrep.Codec.BinaryCodec (Refined.WithRefine.WithRefine 'Refined.WithRefine.Enforced (Binrep.Types.Strings.LenPfx size e) [a]) instance Binrep.Codec.BinaryCodec (Refined.WithRefine.WithRefine 'Refined.WithRefine.Enforced Binrep.Types.Strings.WellSized (Binrep.Types.Strings.Str ('Binrep.Types.Strings.Pascal 'Binrep.Types.Ints.I1 e))) instance Binrep.ByteLen.ByteLen (Binrep.Types.Strings.Str 'Binrep.Types.Strings.C) instance Binrep.ByteLen.ByteLen (Binrep.Types.Ints.I 'Binrep.Types.Ints.U size e) => Binrep.ByteLen.ByteLen (Binrep.Types.Strings.Str ('Binrep.Types.Strings.Pascal size e)) instance Binrep.Codec.BinaryCodec (Binrep.Types.Strings.Str 'Binrep.Types.Strings.C) instance Binrep.Codec.BinaryCodecWith _r (Binrep.Types.Strings.Str 'Binrep.Types.Strings.C) instance Binrep.Codec.BinaryCodecWith Binrep.Types.Strings.StrRep Data.ByteString.Internal.ByteString module Binrep.Predicates.NullPadTo data NullPadTo (n :: Nat) getNNulls :: Natural -> Get () instance GHC.TypeNats.KnownNat n => Binrep.ByteLen.ByteLen (Refined.WithRefine.WithRefine 'Refined.WithRefine.Enforced (Binrep.Predicates.NullPadTo.NullPadTo n) a) instance (Binrep.ByteLen.ByteLen a, GHC.TypeNats.KnownNat n) => Refined.Predicate (Binrep.Predicates.NullPadTo.NullPadTo n) a instance (Binrep.Codec.BinaryCodec a, Binrep.ByteLen.ByteLen a, GHC.TypeNats.KnownNat n) => Binrep.Codec.BinaryCodec (Refined.WithRefine.WithRefine 'Refined.WithRefine.Enforced (Binrep.Predicates.NullPadTo.NullPadTo n) a)