-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Encode precise binary representations directly in types -- -- Please see README.md. @package binrep @version 1.0.0 module Binrep.Common.Class.TypeErrors -- | Common type error string for when you attempt to use a binrep instance -- at an empty data type (e.g. Void, V1). type ENoEmpty = 'Text "No binary representation for empty data type" -- | Common type error string for when you attempt to use a binrep instance -- at a sum data type GHC is asked to derive a non-sum instance, but the -- data type in question turns out to be a sum data type. -- -- No need to add the data type name here, since GHC's context includes -- the surrounding instance declaration. type ENoSum = 'Text "No binary representation for unannotated sum data type" ':$$: 'Text "Consider defining a custom data type" ':<>: 'Text " and deriving a generic instance with explicit sum handling" module Binrep.Common.Via.Generically.NonSum newtype GenericallyNonSum a GenericallyNonSum :: a -> GenericallyNonSum a [unGenericallyNonSum] :: GenericallyNonSum a -> a module Binrep.Common.Via.Prim -- | DerivingVia newtype for types which can borrow from Prim'. newtype ViaPrim a ViaPrim :: a -> ViaPrim a [unViaPrim] :: ViaPrim a -> a module Binrep.Example.Tga data Header (s :: Strength) (a :: k) Header :: SW s Word8 -> ColorMapType -> ImageType -> Header (s :: Strength) (a :: k) [idLen] :: Header (s :: Strength) (a :: k) -> SW s Word8 [colorMapType] :: Header (s :: Strength) (a :: k) -> ColorMapType [imageType] :: Header (s :: Strength) (a :: k) -> ImageType data ColorMapType -- | 0 NoColorMap :: ColorMapType -- | 1 HasColorMap :: ColorMapType data ImageType NoImageData :: ImageType UncompColorMapped :: ImageType UncompTrueColor :: ImageType UncompBW :: ImageType RLEColorMapped :: ImageType RLETrueColor :: ImageType RLEBW :: ImageType -- | Common parser error definitions. module Binrep.Get.Error -- | Top-level parse error. -- -- The final element is the concrete error. Prior elements should -- "contain" the error (i.e. be the larger part that the error occurred -- in). -- -- Really should be non-empty-- but by using List, we can use the empty -- list for Fail. Bit of a cute cheat. type ParseError pos text = [ParseErrorSingle pos text] -- | A single indexed parse error. data ParseErrorSingle pos text ParseErrorSingle :: pos -> [text] -> ParseErrorSingle pos text [parseErrorSinglePos] :: ParseErrorSingle pos text -> pos [parseErrorSingleText] :: ParseErrorSingle pos text -> [text] -- | Map over the pos index type of a ParseErrorSingle. mapParseErrorSinglePos :: (pos1 -> pos2) -> ParseErrorSingle pos1 text -> ParseErrorSingle pos2 text -- | Shorthand for one parse error. parseError1 :: [text] -> pos -> ParseError pos text -- | Construct a parse error message for a generic field failure. parseErrorTextGenericFieldBld :: String -> String -> Maybe String -> Natural -> [Builder] -- | Construct a parse error message for a generic sum tag no-match. parseErrorTextGenericNoCstrMatchBld :: String -> [Builder] -- | Construct a parse error message for a generic sum tag parse error. parseErrorTextGenericSumTagBld :: String -> [Builder] instance (GHC.Show.Show pos, GHC.Show.Show text) => GHC.Show.Show (Binrep.Get.Error.ParseErrorSingle pos text) module Binrep.Type.Text.Internal type Bytes = ByteString -- | A string of a given encoding, stored in the Text type. -- -- Essentially Text carrying a proof that it can be successfully -- encoded into the given encoding. For example, AsText -- ASCII means the Text stored is pure ASCII. type AsText (enc :: k) = Refined enc Text -- | Bytestring encoders for text validated for a given encoding. class Encode (enc :: k) -- | Encode text to bytes. Internal function, use encode. encode' :: Encode enc => Text -> Bytes class Decode (enc :: k) -- | Decode a ByteString to Text with an explicit encoding. -- -- This is intended to be used with visible type applications. decode :: Decode enc => Bytes -> Either String (AsText enc) -- | Helper for decoding a Bytes to a Text tagged with its -- encoding. decodeText :: forall {k} (enc :: k) e. (e -> String) -> (Bytes -> Either e Text) -> Bytes -> Either String (AsText enc) -- | Run an unsafe decoder safely. -- -- Copied from Data.Text.Encoding.decodeUtf8', so should be -- bulletproof? wrapUnsafeDecoder :: (Bytes -> Text) -> Bytes -> Either UnicodeException Text module Binrep.Type.Text.Encoding.Utf8 data Utf8 instance Binrep.Type.Text.Internal.Decode Binrep.Type.Text.Encoding.Utf8.Utf8 instance Binrep.Type.Text.Internal.Encode Binrep.Type.Text.Encoding.Utf8.Utf8 instance Rerefined.Predicate.Predicate Binrep.Type.Text.Encoding.Utf8.Utf8 instance Rerefined.Predicate.Refine Binrep.Type.Text.Encoding.Utf8.Utf8 Data.Text.Internal.Text module Binrep.Type.Text.Encoding.ShiftJis data ShiftJis -- | Encode some Text to the given character set using text-icu. -- -- No guarantees about correctness. Encodings are weird. e.g. Shift JIS's -- yen/backslash problem is apparently to do with OSs treating it -- differently. -- -- Expects a Text that is confirmed valid for converting to the -- character set. -- -- The charset must be valid, or it's exception time. See text-icu. encodeViaTextICU :: String -> Text -> IO ByteString encodeViaTextICU' :: String -> Text -> ByteString decodeViaTextICU :: String -> ByteString -> IO (Either String Text) decodeViaTextICU' :: String -> ByteString -> Either String Text instance Binrep.Type.Text.Internal.Decode Binrep.Type.Text.Encoding.ShiftJis.ShiftJis instance Binrep.Type.Text.Internal.Encode Binrep.Type.Text.Encoding.ShiftJis.ShiftJis instance Rerefined.Predicate.Predicate Binrep.Type.Text.Encoding.ShiftJis.ShiftJis instance Rerefined.Predicate.Refine Binrep.Type.Text.Encoding.ShiftJis.ShiftJis Data.Text.Internal.Text module Binrep.Type.Text.Encoding.Ascii -- | 7-bit data Ascii instance Binrep.Type.Text.Internal.Decode Binrep.Type.Text.Encoding.Ascii.Ascii instance Binrep.Type.Text.Internal.Encode Binrep.Type.Text.Encoding.Ascii.Ascii instance Rerefined.Predicate.Predicate Binrep.Type.Text.Encoding.Ascii.Ascii instance Rerefined.Predicate.Refine Binrep.Type.Text.Encoding.Ascii.Ascii Data.Text.Internal.Text module Binrep.Util.ByteOrder -- | Byte ordering. data ByteOrder -- | most-significant-byte occurs in lowest address. BigEndian :: ByteOrder -- | least-significant-byte occurs in lowest address. LittleEndian :: ByteOrder newtype ByteOrdered (end :: ByteOrder) a ByteOrdered :: a -> ByteOrdered (end :: ByteOrder) a [unByteOrdered] :: ByteOrdered (end :: ByteOrder) a -> a type family EndianSuffix (end :: ByteOrder) :: Symbol type LE = 'LittleEndian type BE = 'BigEndian type Endian = ByteOrdered instance Strongweak.Strengthen.Strengthen a => Strongweak.Strengthen.Strengthen (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance Strongweak.Weaken.Weaken a => Strongweak.Weaken.Weaken (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) module Binrep.Type.Text.Encoding.Utf32 data Utf32 (end :: ByteOrder) instance Binrep.Type.Text.Internal.Decode (Binrep.Type.Text.Encoding.Utf32.Utf32 Binrep.Util.ByteOrder.BE) instance Binrep.Type.Text.Internal.Decode (Binrep.Type.Text.Encoding.Utf32.Utf32 Binrep.Util.ByteOrder.LE) instance Binrep.Type.Text.Internal.Encode (Binrep.Type.Text.Encoding.Utf32.Utf32 Binrep.Util.ByteOrder.BE) instance Binrep.Type.Text.Internal.Encode (Binrep.Type.Text.Encoding.Utf32.Utf32 Binrep.Util.ByteOrder.LE) instance Rerefined.Predicate.Predicate (Binrep.Type.Text.Encoding.Utf32.Utf32 end) instance Rerefined.Predicate.Refine (Binrep.Type.Text.Encoding.Utf32.Utf32 end) Data.Text.Internal.Text module Binrep.Type.Text.Encoding.Utf16 data Utf16 (end :: ByteOrder) instance Binrep.Type.Text.Internal.Decode (Binrep.Type.Text.Encoding.Utf16.Utf16 Binrep.Util.ByteOrder.BE) instance Binrep.Type.Text.Internal.Decode (Binrep.Type.Text.Encoding.Utf16.Utf16 Binrep.Util.ByteOrder.LE) instance Binrep.Type.Text.Internal.Encode (Binrep.Type.Text.Encoding.Utf16.Utf16 Binrep.Util.ByteOrder.BE) instance Binrep.Type.Text.Internal.Encode (Binrep.Type.Text.Encoding.Utf16.Utf16 Binrep.Util.ByteOrder.LE) instance Rerefined.Predicate.Predicate (Binrep.Type.Text.Encoding.Utf16.Utf16 end) instance Rerefined.Predicate.Refine (Binrep.Type.Text.Encoding.Utf16.Utf16 end) Data.Text.Internal.Text module Binrep.Type.Text -- | A string of a given encoding, stored in the Text type. -- -- Essentially Text carrying a proof that it can be successfully -- encoded into the given encoding. For example, AsText -- ASCII means the Text stored is pure ASCII. type AsText (enc :: k) = Refined enc Text -- | Bytestring encoders for text validated for a given encoding. class Encode (enc :: k) -- | Encode text to bytes. Internal function, use encode. encode' :: Encode enc => Text -> Bytes -- | Encode some validated text. encode :: forall {k} (enc :: k). Encode enc => AsText enc -> Bytes -- | Encode some text to a bytestring, asserting that the resulting value -- is valid for the requested bytestring representation. -- -- This is intended to be used with visible type applications: -- --
-- >>> let Right t = refine @UTF8 (Text.pack "hi") -- -- >>> :t t -- t :: AsText UTF8 -- -- >>> let Right bs = encodeToRep @'C t -- -- >>> :t bs -- bs :: Refined 'C Bytes --encodeToRep :: forall {k1} {k2} (rep :: k1) (enc :: k2). (Encode enc, Refine rep Bytes) => AsText enc -> Either RefineFailure (Refined rep Bytes) class Decode (enc :: k) -- | Decode a ByteString to Text with an explicit encoding. -- -- This is intended to be used with visible type applications. decode :: Decode enc => Bytes -> Either String (AsText enc) module Binrep.Type.Prefix.Internal -- | Types which can encode natural (positive integer) lengths. -- -- Types must provide convert to and from Int, which is the most -- common type used for data lengths. class LenNat a where { -- | The maximum value the type can encode. type LenNatMax a :: Natural; -- | The name of the type, to display when used as part of a predicate. type LenNatName a :: Symbol; } -- | Turn an Int length into an a. -- -- It is guaranteed that the Int fits i.e. <= -- LenNatMax a. lenToNat :: LenNat a => Int -> a -- | Turn an a into an Int length. -- -- Don't worry if a may encode larger numbers than Int. I -- think other things will be breaking at that point. Or perhaps it's our -- responsibility to emit the runtime error? TODO. natToLen :: LenNat a => a -> Int instance Binrep.Type.Prefix.Internal.LenNat a => Binrep.Type.Prefix.Internal.LenNat (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance Binrep.Type.Prefix.Internal.LenNat () instance Binrep.Type.Prefix.Internal.LenNat GHC.Word.Word16 instance Binrep.Type.Prefix.Internal.LenNat GHC.Word.Word32 instance Binrep.Type.Prefix.Internal.LenNat GHC.Word.Word64 instance Binrep.Type.Prefix.Internal.LenNat GHC.Word.Word8 module Binrep.Util.Generic -- | Common type error string for when GHC is asked to derive a non-sum -- instance, but the data type in question turns out to be a sum data -- type. -- -- No need to add the data type name here, since GHC's context includes -- the surrounding instance declaration. type EUnexpectedSum = 'Text "Cannot derive non-sum binary representation instance for sum data type" -- | Common type error string for when GHC is asked to derive a sum -- instance, but the data type in question turns out to be a non-sum data -- type. -- -- No need to add the data type name here, since GHC's context includes -- the surrounding instance declaration. type EUnexpectedNonSum = 'Text "Refusing to derive sum binary representation instance for non-sum data type" module Raehik.Compat.FlatParse.Basic.CutWithPos -- | Convert a parsing failure to an error, which also receives the parser -- position (as a Pos, from the end of input). cut' :: forall (st :: ZeroBitType) e a. ParserT st e a -> (Pos -> e) -> ParserT st e a -- | Throw a parsing error, which also receives the parser position (as a -- Pos, from the end of input). err' :: forall e (st :: ZeroBitType) a. (Pos -> e) -> ParserT st e a module Raehik.Compat.FlatParse.Basic.Prim anyPrim :: forall a e (st :: ZeroBitType). Prim' a => ParserT st e a module Raehik.Compat.FlatParse.Basic.WithLength -- | Run a parser, and return the result as well as the number of bytes it -- consumed. parseWithLength :: forall (st :: ZeroBitType) e a. ParserT st e a -> ParserT st e (a, Int) -- | Handy typenat utils. module Util.TypeNats natVal'' :: forall (n :: Nat). KnownNat n => Natural natValInt :: forall (n :: Nat). KnownNat n => Int natValWord :: forall (n :: Nat). KnownNat n => Word module Binrep.CBLen class IsCBLen (a :: k) where { type CBLen (a :: k) :: Natural; } -- | Reify a type's constant byte length to the term level. cblen :: forall {k} (a :: k). KnownNat (CBLen a) => Int cblen# :: forall {k} (a :: k). KnownNat (CBLen a) => Int# cblenProxy# :: forall {k} (a :: k). KnownNat (CBLen a) => Proxy# a -> Int# -- | Defunctionalization symbol for CBLen. -- -- This is required for parameterized type-level generics e.g. bytezap's -- GPokeBase. data CBLenSym (a1 :: FunKind a Natural) -- | Using this necessitates UndecidableInstances. type CBLenGenericSum w a = GCBLen w Rep a -- | Using this necessitates UndecidableInstances. type CBLenGenericNonSum a = GTFoldMapCAddition CBLenSym :: FunKind Type Natural -> Type Rep a type family GCBLen (w :: k) (gf :: k1 -> Type) :: Natural type family GCBLenSum (gf :: k -> Type) type family MaybeEq a b -- | I don't know how to pattern match in types without writing type -- families. type family GCBLenCaseMaybe a :: k data JustX (a :: k) (b :: k1) data NothingX instance Binrep.CBLen.IsCBLen a => Binrep.CBLen.IsCBLen (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance GHC.Generics.Generic a => Binrep.CBLen.IsCBLen (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.CBLen.IsCBLen GHC.Int.Int16 instance Binrep.CBLen.IsCBLen GHC.Int.Int32 instance Binrep.CBLen.IsCBLen GHC.Int.Int64 instance Binrep.CBLen.IsCBLen GHC.Int.Int8 instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.CBLen.IsCBLen (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.CBLen.IsCBLen (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance (Binrep.CBLen.IsCBLen l, Binrep.CBLen.IsCBLen r) => Binrep.CBLen.IsCBLen (l, r) instance Binrep.CBLen.IsCBLen () instance Binrep.CBLen.IsCBLen GHC.Word.Word16 instance Binrep.CBLen.IsCBLen GHC.Word.Word32 instance Binrep.CBLen.IsCBLen GHC.Word.Word64 instance Binrep.CBLen.IsCBLen GHC.Word.Word8 module Binrep.Put.Struct type PutterC = Poke RealWorld -- | constant size putter class PutC a putC :: PutC a => a -> PutterC runPutC :: (PutC a, KnownNat (CBLen a)) => a -> ByteString -- | Serialize a term of the struct-like type a via its -- Generic instance. putGenericStruct :: (Generic a, GPoke PutC (Rep a), GAssertNotVoid a, GAssertNotSum a) => a -> PutterC instance Bytezap.Struct.Generic.GPokeBase Binrep.Put.Struct.PutC instance Binrep.Put.Struct.PutC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Word.Word8) instance Binrep.Put.Struct.PutC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Int.Int8) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Put.Struct.PutC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Put.Struct.PutC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance (TypeError ...) => Binrep.Put.Struct.PutC (Data.Either.Either a b) instance (GHC.Generics.Generic a, Bytezap.Struct.Generic.GPoke Binrep.Put.Struct.PutC (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Put.Struct.PutC (GHC.Generics.Generically a) instance (GHC.Generics.Generic a, Bytezap.Struct.Generic.GPoke Binrep.Put.Struct.PutC (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Put.Struct.PutC (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.Put.Struct.PutC a => Binrep.Put.Struct.PutC (Data.Functor.Identity.Identity a) instance Binrep.Put.Struct.PutC GHC.Int.Int8 instance Binrep.Put.Struct.PutC Binrep.Put.Struct.PutterC instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.Put.Struct.PutC (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.Put.Struct.PutC (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance (Binrep.Put.Struct.PutC l, GHC.TypeNats.KnownNat (Binrep.CBLen.CBLen l), Binrep.Put.Struct.PutC r) => Binrep.Put.Struct.PutC (l, r) instance Binrep.Put.Struct.PutC () instance Raehik.Compat.Data.Primitive.Types.Prim' a => Binrep.Put.Struct.PutC (Binrep.Common.Via.Prim.ViaPrim a) instance (TypeError ...) => Binrep.Put.Struct.PutC GHC.Base.Void instance Binrep.Put.Struct.PutC GHC.Word.Word8 module Binrep.Get.Struct type GetterC = Parser ParseError Int Builder -- | constant size parser class GetC a getC :: GetC a => GetterC a -- | Serialize a term of the struct-like type a via its -- Generic instance. getGenericStruct :: (Generic a, GParse GetC (Rep a), GAssertNotVoid a, GAssertNotSum a) => GetterC a runGetCBs :: (GetC a, KnownNat (CBLen a)) => ByteString -> Either (ParseError Int Builder) a -- | doesn't check len unsafeRunGetCPtr :: GetC a => Ptr Word8 -> Either (ParseError Int Builder) a instance Bytezap.Parser.Struct.Generic.GParseBase Binrep.Get.Struct.GetC instance Binrep.Get.Struct.GetC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Word.Word8) instance Binrep.Get.Struct.GetC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Int.Int8) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Get.Struct.GetC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Get.Struct.GetC (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance (GHC.Generics.Generic a, Bytezap.Parser.Struct.Generic.GParse Binrep.Get.Struct.GetC (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Get.Struct.GetC (GHC.Generics.Generically a) instance (GHC.Generics.Generic a, Bytezap.Parser.Struct.Generic.GParse Binrep.Get.Struct.GetC (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Get.Struct.GetC (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.Get.Struct.GetC a => Binrep.Get.Struct.GetC (Data.Functor.Identity.Identity a) instance Binrep.Get.Struct.GetC GHC.Int.Int8 instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.Get.Struct.GetC (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.Get.Struct.GetC (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance Binrep.Get.Struct.GetC () instance Raehik.Compat.Data.Primitive.Types.Prim' a => Binrep.Get.Struct.GetC (Binrep.Common.Via.Prim.ViaPrim a) instance Binrep.Get.Struct.GetC GHC.Word.Word8 module Binrep.Get class Get a -- | Parse from binary. get :: Get a => Getter a runGet :: Get a => ByteString -> Either (ParseError Int Builder) (a, ByteString) -- | Turn a Fail into a single error, or prepend it to any existing -- ones. -- -- Use when wrapping other getters. -- -- We reimplement cutting with a tweak. Otherwise, we'd have to -- join lists in the error case (instead of simply prepending). cutting1 :: forall (st :: ZeroBitType) text a. ParserT st (ParseError Pos text) a -> [text] -> ParserT st (ParseError Pos text) a type Getter = Parser ParseError Pos Builder runGetter :: Getter a -> ByteString -> Either (ParseError Int Builder) (a, ByteString) getGenericNonSum :: (Generic a, GTraverseNonSum Get (Rep a), GAssertNotVoid a, GAssertNotSum a) => Getter a getGenericSum :: forall {k} (sumtag :: k) pt a. (Generic a, GTraverseSum Get sumtag (Rep a), Get pt, GAssertNotVoid a, GAssertSum a) => ParseCstrTo sumtag pt -> (pt -> pt -> Bool) -> Getter a -- | Emit a single error. Use with flatparse primitives that only -- Fail. err1 :: forall text (st :: ZeroBitType) a. [text] -> ParserT st (ParseError Pos text) a getGenericSumRaw :: forall pt a. (Generic a, GTraverseSum Get Raw (Rep a), Get pt, GAssertNotVoid a, GAssertSum a) => (String -> pt) -> (pt -> pt -> Bool) -> Getter a -- | Turn a Fail into a single error. (Re-emits existing -- Errors.) -- -- Use when wrapping flatparse primitives that directly only Fail. -- (It's fine to use with combinators if the combinator itself doesn't -- Error.) cut1 :: forall (st :: ZeroBitType) text a. ParserT st (ParseError Pos text) a -> [text] -> ParserT st (ParseError Pos text) a fpToBz :: forall (st :: ZeroBitType) text a r. ParserT st (ParseError Pos text) a -> Int# -> (a -> Int# -> ParserT st (ParseError Int text) r) -> ParserT st (ParseError Int text) r newtype ViaGetC a ViaGetC :: a -> ViaGetC a [unViaGetC] :: ViaGetC a -> a bzToFp :: KnownNat (CBLen a) => GetterC a -> Getter a -- | Parse any Prim'. getPrim :: Prim' a => Getter a instance Generic.Data.FOnCstr.GenericFOnCstr Binrep.Get.Get instance Generic.Data.Function.Traverse.Constructor.GenericTraverse Binrep.Get.Get instance Binrep.Get.Get (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Word.Word8) instance Binrep.Get.Get (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Int.Int8) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Get.Get (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Get.Get (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance Binrep.Get.Get Data.ByteString.Internal.Type.ByteString instance (TypeError ...) => Binrep.Get.Get (Data.Either.Either a b) instance (GHC.Generics.Generic a, Generic.Data.Function.Traverse.NonSum.GTraverseNonSum Binrep.Get.Get (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Get.Get (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.Get.Get a => Binrep.Get.Get (Data.Functor.Identity.Identity a) instance Binrep.Get.Get GHC.Int.Int8 instance Binrep.Get.Get a => Binrep.Get.Get [a] instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.Get.Get (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.Get.Get (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance (Binrep.Get.Get l, Binrep.Get.Get r) => Binrep.Get.Get (l, r) instance Binrep.Get.Get () instance (Binrep.Get.Struct.GetC a, GHC.TypeNats.KnownNat (Binrep.CBLen.CBLen a)) => Binrep.Get.Get (Binrep.Get.ViaGetC a) instance Raehik.Compat.Data.Primitive.Types.Prim' a => Binrep.Get.Get (Binrep.Common.Via.Prim.ViaPrim a) instance (TypeError ...) => Binrep.Get.Get GHC.Base.Void instance Binrep.Get.Get GHC.Word.Word8 -- | Byte length as a simple pure function, no bells or whistles. -- -- Non-reallocating serializers like store, bytezap or ptr-poker request -- the expected total byte length when serializing. Thus, they need some -- way to measure byte length *before* serializing. This is that. -- -- It should be very efficient to calculate serialized byte length for -- most binrep-compatible Haskell types. If it isn't, consider whether -- the representation is appropriate for binrep. -- -- Note that you _may_ encode this inside the serializer type (whatever -- the Put class stores). I went back and forth on this a couple -- times. But some binrep code seems to make more sense when byte length -- is standalone. And I don't mind the extra explicitness. So it's here -- to stay :) module Binrep.BLen -- | Class for types with easily-calculated length in bytes. -- -- If it appears hard to calculate byte length for a given type (e.g. -- without first serializing it, then measuring serialized byte length), -- consider whether this type is a good fit for binrep. class BLen a -- | Calculate the serialized byte length of the given value. blen :: BLen a => a -> Int -- | Measure the byte length of a term of the non-sum type a via -- its Generic instance. blenGenericNonSum :: (Generic a, GFoldMapNonSum BLen (Rep a), GAssertNotVoid a, GAssertNotSum a) => a -> Int -- | Measure the byte length of a term of the sum type a via its -- Generic instance. blenGenericSum :: forall {k} (sumtag :: k) a. (Generic a, GFoldMapSum BLen sumtag (Rep a), GAssertNotVoid a, GAssertSum a) => ParseCstrTo sumtag Int -> a -> Int -- | Measure the byte length of a term of the sum type a via its -- Generic instance. blenGenericSumRaw :: (Generic a, GFoldMapSum BLen Raw (Rep a), GAssertNotVoid a, GAssertSum a) => (String -> Int) -> a -> Int -- | DerivingVia wrapper for types which may derive a BLen instance -- through an existing IsCBLen instance (i.e. it is known at -- compile time) -- -- Examples of such types include machine integers, and explicitly-sized -- types (e.g. Binrep.Type.Sized). newtype ViaCBLen a ViaCBLen :: a -> ViaCBLen a [unViaCBLen] :: ViaCBLen a -> a -- | Reify a type's constant byte length to the term level. cblen :: forall {k} (a :: k). KnownNat (CBLen a) => Int instance GHC.TypeNats.KnownNat (Binrep.CBLen.CBLen a) => Binrep.BLen.BLen (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end a) instance Binrep.BLen.BLen Data.ByteString.Internal.Type.ByteString instance (TypeError ...) => Binrep.BLen.BLen (Data.Either.Either a b) instance (GHC.Generics.Generic a, Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum Binrep.BLen.BLen (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.BLen.BLen (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.BLen.BLen GHC.Int.Int16 instance Binrep.BLen.BLen GHC.Int.Int32 instance Binrep.BLen.BLen GHC.Int.Int64 instance Binrep.BLen.BLen GHC.Int.Int8 instance Binrep.BLen.BLen a => Binrep.BLen.BLen [a] instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.BLen.BLen (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.BLen.BLen (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance (Binrep.BLen.BLen l, Binrep.BLen.BLen r) => Binrep.BLen.BLen (l, r) instance Binrep.BLen.BLen () instance GHC.TypeNats.KnownNat (Binrep.CBLen.CBLen a) => Binrep.BLen.BLen (Binrep.BLen.ViaCBLen a) instance (TypeError ...) => Binrep.BLen.BLen GHC.Base.Void instance Binrep.BLen.BLen GHC.Word.Word16 instance Binrep.BLen.BLen GHC.Word.Word32 instance Binrep.BLen.BLen GHC.Word.Word64 instance Binrep.BLen.BLen GHC.Word.Word8 instance Generic.Data.Function.FoldMap.Constructor.GenericFoldMap Binrep.BLen.BLen module Binrep.Put type Putter = Poke RealWorld class Put a put :: Put a => a -> Putter runPut :: (BLen a, Put a) => a -> ByteString -- | Serialize a term of the non-sum type a via its Generic -- instance. putGenericNonSum :: (Generic a, GFoldMapNonSum Put (Rep a), GAssertNotVoid a, GAssertNotSum a) => a -> Putter -- | Serialize a term of the sum type a via its Generic -- instance. putGenericSum :: forall {k} (sumtag :: k) a. (Generic a, GFoldMapSum Put sumtag (Rep a), GAssertNotVoid a, GAssertSum a) => ParseCstrTo sumtag Putter -> a -> Putter -- | Serialize a term of the sum type a via its Generic -- instance, without pre-parsing constructor names. putGenericSumRaw :: (Generic a, GFoldMapSum Put Raw (Rep a), GAssertNotVoid a, GAssertSum a) => (String -> Putter) -> a -> Putter newtype ViaPutC a ViaPutC :: a -> ViaPutC a [unViaPutC] :: ViaPutC a -> a instance Generic.Data.Function.FoldMap.Constructor.GenericFoldMap Binrep.Put.Put instance Binrep.Put.Put (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Word.Word8) instance Binrep.Put.Put (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered end GHC.Int.Int8) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Put.Put (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.LittleEndian a) instance (Raehik.Compat.Data.Primitive.Types.Prim' a, Raehik.Compat.Data.Primitive.Types.Endian.ByteSwap a) => Binrep.Put.Put (Raehik.Compat.Data.Primitive.Types.Endian.ByteOrdered 'GHC.ByteOrder.BigEndian a) instance Binrep.Put.Put Data.ByteString.Internal.Type.ByteString instance (TypeError ...) => Binrep.Put.Put (Data.Either.Either a b) instance (GHC.Generics.Generic a, Generic.Data.Function.FoldMap.NonSum.GFoldMapNonSum Binrep.Put.Put (GHC.Generics.Rep a), Generic.Type.Assert.GAssertNotVoid a, Generic.Type.Assert.GAssertNotSum a) => Binrep.Put.Put (Binrep.Common.Via.Generically.NonSum.GenericallyNonSum a) instance Binrep.Put.Put a => Binrep.Put.Put (Data.Functor.Identity.Identity a) instance Binrep.Put.Put GHC.Int.Int8 instance Binrep.Put.Put a => Binrep.Put.Put [a] instance Binrep.Put.Put Binrep.Put.Putter instance forall k1 k (pr :: k1) (pl :: k) a. Binrep.Put.Put (Rerefined.Refine.Refined pr (Rerefined.Refine.Refined pl a)) => Binrep.Put.Put (Rerefined.Refine.Refined (Rerefined.Predicate.Logical.And.And pl pr) a) instance (Binrep.Put.Put l, Binrep.Put.Put r) => Binrep.Put.Put (l, r) instance Binrep.Put.Put () instance Raehik.Compat.Data.Primitive.Types.Prim' a => Binrep.Put.Put (Binrep.Common.Via.Prim.ViaPrim a) instance (Binrep.Put.Struct.PutC a, GHC.TypeNats.KnownNat (Binrep.CBLen.CBLen a)) => Binrep.Put.Put (Binrep.Put.ViaPutC a) instance (TypeError ...) => Binrep.Put.Put GHC.Base.Void instance Binrep.Put.Put GHC.Word.Word8 -- | Top-level binrep module, exporting all classes, generics & -- runners. -- -- binrep helps you precisely model binary schemas by combining simple -- "building blocks" (e.g. NullTerminated a) in regular -- Haskell types. You can then receive high-performance serializers and -- parsers for free via generics. -- -- binrep is not a general-purpose parsing/serializing library. -- For that, see -- --
-- class Copy a where copy :: a -> a -- instance Copy B.ByteString where copy = B.copy ---- -- But this just doesn't fly, because it would invert the behaviour. module Binrep.Type.Thin newtype Thin a Thin :: a -> Thin a [unThin] :: Thin a -> a instance Binrep.BLen.BLen a => Binrep.BLen.BLen (Binrep.Type.Thin.Thin a) instance Data.Data.Data a => Data.Data.Data (Binrep.Type.Thin.Thin a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Binrep.Type.Thin.Thin a) instance GHC.Generics.Generic (Binrep.Type.Thin.Thin a) instance Binrep.Get.Get (Binrep.Type.Thin.Thin Data.ByteString.Internal.Type.ByteString) instance GHC.IsList.IsList a => GHC.IsList.IsList (Binrep.Type.Thin.Thin a) instance Data.String.IsString a => Data.String.IsString (Binrep.Type.Thin.Thin a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Binrep.Type.Thin.Thin a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Binrep.Type.Thin.Thin a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Binrep.Type.Thin.Thin a) instance Binrep.Put.Put a => Binrep.Put.Put (Binrep.Type.Thin.Thin a) instance GHC.Read.Read a => GHC.Read.Read (Binrep.Type.Thin.Thin a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Binrep.Type.Thin.Thin a) instance GHC.Show.Show a => GHC.Show.Show (Binrep.Type.Thin.Thin a) instance Strongweak.Strengthen.Strengthen (Binrep.Type.Thin.Thin a) instance Strongweak.Weaken.Weaken (Binrep.Type.Thin.Thin a) -- | Constant-size data. module Binrep.Type.Sized -- | Essentially runtime reflection of a BLen type to CBLen. data Size (n :: Natural) type Sized (n :: Natural) = Refined Size n instance GHC.TypeNats.KnownNat n => Binrep.BLen.BLen (Binrep.Type.Sized.Sized n a) instance (Binrep.Get.Get a, GHC.TypeNats.KnownNat n) => Binrep.Get.Get (Binrep.Type.Sized.Sized n a) instance Binrep.CBLen.IsCBLen (Binrep.Type.Sized.Sized n a) instance Rerefined.Predicate.Predicate (Binrep.Type.Sized.Size n) instance Binrep.Put.Struct.PutC a => Binrep.Put.Struct.PutC (Binrep.Type.Sized.Sized n a) instance Binrep.Put.Put a => Binrep.Put.Put (Binrep.Type.Sized.Sized n a) instance (Rerefined.Predicate.KnownPredicateName (Binrep.Type.Sized.Size n), Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Rerefined.Predicate.Refine (Binrep.Type.Sized.Size n) a module Binrep.Type.Prefix.Size data SizePrefix pfx type SizePrefixed pfx = Refined SizePrefix pfx class GetSize a getSize :: GetSize a => Int -> Getter a instance (Binrep.Type.Prefix.Internal.LenNat pfx, Binrep.BLen.BLen a, Binrep.BLen.BLen pfx) => Binrep.BLen.BLen (Binrep.Type.Prefix.Size.SizePrefixed pfx a) instance (Binrep.Type.Prefix.Internal.LenNat pfx, Binrep.Type.Prefix.Size.GetSize a, Binrep.Get.Get pfx) => Binrep.Get.Get (Binrep.Type.Prefix.Size.SizePrefixed pfx a) instance Binrep.Type.Prefix.Size.GetSize Data.ByteString.Internal.Type.ByteString instance Binrep.Type.Prefix.Size.GetSize (Binrep.Type.Thin.Thin Data.ByteString.Internal.Type.ByteString) instance Binrep.CBLen.IsCBLen (Binrep.Type.Prefix.Size.SizePrefixed pfx a) instance Rerefined.Predicate.Predicate (Binrep.Type.Prefix.Size.SizePrefix pfx) instance (Binrep.Type.Prefix.Internal.LenNat pfx, Binrep.BLen.BLen a, Binrep.Put.Put pfx, Binrep.Put.Put a) => Binrep.Put.Put (Binrep.Type.Prefix.Size.SizePrefixed pfx a) instance (Rerefined.Predicate.KnownPredicateName (Binrep.Type.Prefix.Size.SizePrefix pfx), GHC.TypeNats.KnownNat (Binrep.Type.Prefix.Internal.LenNatMax pfx), Binrep.BLen.BLen a) => Rerefined.Predicate.Refine (Binrep.Type.Prefix.Size.SizePrefix pfx) a module Binrep.Type.Prefix.Count data CountPrefix pfx type CountPrefixed pfx = Refined1 CountPrefix pfx :: k1 -> Type -> k1 -> Type class GetCount (f :: Type -> Type) getCount :: (GetCount f, Get a) => Int -> Getter (f a) instance (Binrep.Type.Prefix.Internal.LenNat pfx, Data.Foldable.Foldable f, Binrep.BLen.BLen pfx, Binrep.BLen.BLen (f a)) => Binrep.BLen.BLen (Binrep.Type.Prefix.Count.CountPrefixed pfx f a) instance Binrep.Type.Prefix.Count.GetCount [] instance (Binrep.Type.Prefix.Internal.LenNat pfx, Binrep.Type.Prefix.Count.GetCount f, Binrep.Get.Get pfx, Binrep.Get.Get a) => Binrep.Get.Get (Binrep.Type.Prefix.Count.CountPrefixed pfx f a) instance forall k1 pfx (f :: k1 -> GHC.Types.Type) (a :: k1). Binrep.CBLen.IsCBLen (Binrep.Type.Prefix.Count.CountPrefixed pfx f a) instance Rerefined.Predicate.Predicate (Binrep.Type.Prefix.Count.CountPrefix pfx) instance (Binrep.Type.Prefix.Internal.LenNat pfx, Data.Foldable.Foldable f, Binrep.Put.Put pfx, Binrep.Put.Put (f a)) => Binrep.Put.Put (Binrep.Type.Prefix.Count.CountPrefixed pfx f a) instance (Rerefined.Predicate.KnownPredicateName (Binrep.Type.Prefix.Count.CountPrefix pfx), GHC.TypeNats.KnownNat (Binrep.Type.Prefix.Internal.LenNatMax pfx), Data.Foldable.Foldable f) => Rerefined.Predicate.Refine1 (Binrep.Type.Prefix.Count.CountPrefix pfx) f instance (Rerefined.Predicate.KnownPredicateName (Binrep.Type.Prefix.Count.CountPrefix pfx), GHC.TypeNats.KnownNat (Binrep.Type.Prefix.Internal.LenNatMax pfx), Data.Foldable.Foldable f) => Rerefined.Predicate.Refine (Binrep.Type.Prefix.Count.CountPrefix pfx) (f a) -- | C-style null-terminated data. -- -- I mix string and bytestring terminology here, due to bad C influences. -- This module is specifically interested in bytestrings and their -- encoding. String/text encoding is handled in Text. module Binrep.Type.NullTerminated -- | Null-terminated data. Arbitrary length terminated with a null byte. -- Permits no null bytes inside the data. data NullTerminate type NullTerminated = Refined NullTerminate instance Binrep.BLen.BLen a => Binrep.BLen.BLen (Binrep.Type.NullTerminated.NullTerminated a) instance Binrep.Get.Get a => Binrep.Get.Get (Binrep.Type.NullTerminated.NullTerminated a) instance Rerefined.Predicate.Predicate Binrep.Type.NullTerminated.NullTerminate instance Binrep.Put.Put a => Binrep.Put.Put (Binrep.Type.NullTerminated.NullTerminated a) instance Rerefined.Predicate.Refine Binrep.Type.NullTerminated.NullTerminate Data.ByteString.Internal.Type.ByteString module Binrep.Generic -- | Turn a constructor name into a prefix tag by adding a null terminator. -- -- Not common in binary data representations, but safe and useful for -- debugging. -- -- reallyUnsafeRefine : safe assuming Haskell constructor names are UTF-8 -- with no null bytes allowed nullTermCstrPfxTag :: String -> NullTerminated ByteString -- | Data null-padded to a given length. module Binrep.Type.NullPadded data NullPad (n :: Natural) -- | A type which is to be null-padded to a given total length. -- -- Given some a :: NullPadded n a, it is guaranteed that -- --
-- blen a <= natValInt @n ---- -- thus -- --
-- natValInt @n - blen a >= 0 ---- -- That is, the serialized stored data will not be longer than the total -- length. type NullPadded (n :: Natural) a = Refined NullPad n a instance GHC.TypeNats.KnownNat n => Binrep.BLen.BLen (Binrep.Type.NullPadded.NullPadded n a) instance (GHC.TypeNats.KnownNat n, Binrep.Get.Get a) => Binrep.Get.Struct.GetC (Binrep.Type.NullPadded.NullPadded n a) instance (Binrep.Get.Get a, GHC.TypeNats.KnownNat n) => Binrep.Get.Get (Binrep.Type.NullPadded.NullPadded n a) instance Binrep.CBLen.IsCBLen (Binrep.Type.NullPadded.NullPadded n a) instance Rerefined.Predicate.Predicate (Binrep.Type.NullPadded.NullPad n) instance (Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n, Binrep.Put.Put a) => Binrep.Put.Struct.PutC (Binrep.Type.NullPadded.NullPadded n a) instance (Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n, Binrep.Put.Put a) => Binrep.Put.Put (Binrep.Type.NullPadded.NullPadded n a) instance (Rerefined.Predicate.KnownPredicateName (Binrep.Type.NullPadded.NullPad n), Binrep.BLen.BLen a, GHC.TypeNats.KnownNat n) => Rerefined.Predicate.Refine (Binrep.Type.NullPadded.NullPad n) a -- | Null-terminated, then null-padded data. -- -- This is defined using the composition of existing NullTerminate -- and NullPad predicates, plus the re-associating binrep -- instances for the And predicate combinator. It kind of just -- magically works. module Binrep.Type.Derived.NullTermPadded -- | Predicate for null-terminated, then null-padded data. type NullTermPad (n :: Natural) = And NullTerminate NullPad n -- | Null-terminated data, which is then null-padded to the given length. -- -- Instantiate with ByteString for a null-padded C string. type NullTermPadded (n :: Natural) = Refined NullTermPad n -- | Magic numbers (also just magic): short constant bytestrings usually -- found at the top of a file, often used as an early sanity check. -- -- There are two main flavors of magics: -- --