{-# OPTIONS_HADDOCK not-home #-}

-- | Public API for serialisation of keys, blobs and values
--
module Database.LSMTree.Internal.Serialise.Class (
    -- * SerialiseKey
    SerialiseKey (..)
  , serialiseKeyIdentity
  , serialiseKeyIdentityUpToSlicing
  , SerialiseKeyOrderPreserving
  , serialiseKeyPreservesOrdering
    -- * SerialiseValue
  , SerialiseValue (..)
  , serialiseValueIdentity
  , serialiseValueIdentityUpToSlicing
    -- * RawBytes
  , RawBytes (..)
  , packSlice
    -- * Errors
  , requireBytesExactly
  ) where

import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Short.Internal as SBS
import qualified Data.ByteString.UTF8 as UTF8
import           Data.Int (Int16, Int32, Int64, Int8)
import           Data.Monoid (Sum (..))
import qualified Data.Primitive as P
import qualified Data.Vector.Primitive as VP
import           Data.Void (Void, absurd)
import           Data.Word (Word16, Word32, Word64, Word8)
import           Database.LSMTree.Internal.ByteString (byteArrayToSBS)
import           Database.LSMTree.Internal.Primitive
import           Database.LSMTree.Internal.RawBytes (RawBytes (..))
import qualified Database.LSMTree.Internal.RawBytes as RB
import           Database.LSMTree.Internal.Vector
import           Numeric (showInt)

{-------------------------------------------------------------------------------
  SerialiseKey
-------------------------------------------------------------------------------}

{- | Serialisation of keys.

Instances should satisfy the following laws:

[Identity]
  @'deserialiseKey' ('serialiseKey' x) == x@
[Identity up to slicing]
  @'deserialiseKey' ('packSlice' prefix ('serialiseKey' x) suffix) == x@
-}
class SerialiseKey k where
  serialiseKey :: k -> RawBytes
  -- TODO: 'deserialiseKey' is only strictly necessary for range queries.
  -- It might make sense to move it to a separate class, which could also
  -- require total deserialisation (potentially using 'Either').
  deserialiseKey :: RawBytes -> k

-- | Test the __Identity__ law for the 'SerialiseKey' class
serialiseKeyIdentity :: (Eq k, SerialiseKey k) => k -> Bool
serialiseKeyIdentity :: forall k. (Eq k, SerialiseKey k) => k -> Bool
serialiseKeyIdentity k
x = RawBytes -> k
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey (k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x) k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
x

-- | Test the __Identity up to slicing__ law for the 'SerialiseKey' class
serialiseKeyIdentityUpToSlicing ::
     (Eq k, SerialiseKey k)
  => RawBytes -> k -> RawBytes -> Bool
serialiseKeyIdentityUpToSlicing :: forall k.
(Eq k, SerialiseKey k) =>
RawBytes -> k -> RawBytes -> Bool
serialiseKeyIdentityUpToSlicing RawBytes
prefix k
x RawBytes
suffix =
    RawBytes -> k
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey (RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix (k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x) RawBytes
suffix) k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
x

{- |
Order-preserving serialisation of keys.

Table data is sorted by /serialised/ keys.
Range lookups and cursors return entries in this order.
If serialisation does not preserve the ordering of /unserialised/ keys,
then range lookups and cursors return entries out of order.

If the 'SerialiseKey' instance for a type preserves the ordering,
then it can safely be given an instance of 'SerialiseKeyOrderPreserving'.
These should satisfy the following law:

[Order-preserving]
  @x \`'compare'\` y == 'serialiseKey' x \`'compare'\` 'serialiseKey' y@

Serialised keys are lexicographically ordered.
To satisfy the __Order-preserving__ law, keys should be serialised into a big-endian format.
-}
class SerialiseKey k => SerialiseKeyOrderPreserving k where

-- | Test the __Order-preserving__ law for the 'SerialiseKeyOrderPreserving' class
serialiseKeyPreservesOrdering :: (Ord k, SerialiseKey k) => k -> k -> Bool
serialiseKeyPreservesOrdering :: forall k. (Ord k, SerialiseKey k) => k -> k -> Bool
serialiseKeyPreservesOrdering k
x k
y = k
x k -> k -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` k
y Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
x RawBytes -> RawBytes -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` k -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey k
y

{-------------------------------------------------------------------------------
  SerialiseValue
-------------------------------------------------------------------------------}

{- | Serialisation of values and blobs.

Instances should satisfy the following laws:

[Identity]
  @'deserialiseValue' ('serialiseValue' x) == x@

[Identity up to slicing]
  @'deserialiseValue' ('packSlice' prefix ('serialiseValue' x) suffix) == x@
-}
class SerialiseValue v where
  serialiseValue :: v -> RawBytes
  deserialiseValue :: RawBytes -> v

-- | Test the __Identity__ law for the 'SerialiseValue' class
serialiseValueIdentity :: (Eq v, SerialiseValue v) => v -> Bool
serialiseValueIdentity :: forall v. (Eq v, SerialiseValue v) => v -> Bool
serialiseValueIdentity v
x = RawBytes -> v
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue (v -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue v
x) v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
x

-- | Test the __Identity up to slicing__ law for the 'SerialiseValue' class
serialiseValueIdentityUpToSlicing ::
     (Eq v, SerialiseValue v)
  => RawBytes -> v -> RawBytes -> Bool
serialiseValueIdentityUpToSlicing :: forall v.
(Eq v, SerialiseValue v) =>
RawBytes -> v -> RawBytes -> Bool
serialiseValueIdentityUpToSlicing RawBytes
prefix v
x RawBytes
suffix =
    RawBytes -> v
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue (RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix (v -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue v
x) RawBytes
suffix) v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
x

{-------------------------------------------------------------------------------
  RawBytes
-------------------------------------------------------------------------------}

-- | @'packSlice' prefix x suffix@ makes @x@ into a slice with @prefix@ bytes on
-- the left and @suffix@ bytes on the right.
packSlice :: RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice :: RawBytes -> RawBytes -> RawBytes -> RawBytes
packSlice RawBytes
prefix RawBytes
x RawBytes
suffix =
    Int -> RawBytes -> RawBytes
RB.take (RawBytes -> Int
RB.size RawBytes
x) (Int -> RawBytes -> RawBytes
RB.drop (RawBytes -> Int
RB.size RawBytes
prefix) (RawBytes
prefix RawBytes -> RawBytes -> RawBytes
forall a. Semigroup a => a -> a -> a
<> RawBytes
x RawBytes -> RawBytes -> RawBytes
forall a. Semigroup a => a -> a -> a
<> RawBytes
suffix))

{-------------------------------------------------------------------------------
  Errors
-------------------------------------------------------------------------------}

-- | @'requireBytesExactly' tyName expected actual x@
requireBytesExactly :: String -> Int -> Int -> a -> a
requireBytesExactly :: forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
tyName Int
expected Int
actual a
x
  | Int
expected Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
actual = a
x
  | Bool
otherwise          =
        String -> a
forall a. HasCallStack => String -> a
error
      (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"deserialise "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
tyName
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
": expected "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Integral a => a -> ShowS
showInt Int
expected
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" bytes, but got "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Integral a => a -> ShowS
showInt Int
actual
      ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
""

{-------------------------------------------------------------------------------
  Int
-------------------------------------------------------------------------------}

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Int8 where
  serialiseKey :: Int8 -> RawBytes
serialiseKey Int8
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int8 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim Int8
x

  deserialiseKey :: RawBytes -> Int8
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int8 -> Int8
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int8" Int
1 Int
len (Int8 -> Int8) -> Int8 -> Int8
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int8
indexInt8Array ByteArray
ba Int
off

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Int8 where
  serialiseValue :: Int8 -> RawBytes
serialiseValue Int8
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int8 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int8 -> Vector Word8) -> Int8 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int8
x

  deserialiseValue :: RawBytes -> Int8
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int8 -> Int8
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int8" Int
1 Int
len (Int8 -> Int8) -> Int8 -> Int8
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int8
indexInt8Array ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Int16 where
  serialiseKey :: Int16 -> RawBytes
serialiseKey Int16
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int16 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int16 -> Vector Word8) -> Int16 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int16 -> Int16
byteSwapInt16 Int16
x

  deserialiseKey :: RawBytes -> Int16
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int16 -> Int16
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int16" Int
2 Int
len (Int16 -> Int16) -> Int16 -> Int16
forall a b. (a -> b) -> a -> b
$ Int16 -> Int16
byteSwapInt16 (ByteArray -> Int -> Int16
indexWord8ArrayAsInt16 ByteArray
ba Int
off)

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Int16 where
  serialiseValue :: Int16 -> RawBytes
serialiseValue Int16
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int16 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int16 -> Vector Word8) -> Int16 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int16
x

  deserialiseValue :: RawBytes -> Int16
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int16 -> Int16
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int16" Int
2 Int
len (Int16 -> Int16) -> Int16 -> Int16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int16
indexWord8ArrayAsInt16 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Int32 where
  serialiseKey :: Int32 -> RawBytes
serialiseKey Int32
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int32 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int32 -> Vector Word8) -> Int32 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int32 -> Int32
byteSwapInt32 Int32
x

  deserialiseKey :: RawBytes -> Int32
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int32 -> Int32
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int32" Int
4 Int
len (Int32 -> Int32) -> Int32 -> Int32
forall a b. (a -> b) -> a -> b
$ Int32 -> Int32
byteSwapInt32 (ByteArray -> Int -> Int32
indexWord8ArrayAsInt32 ByteArray
ba Int
off)

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Int32 where
  serialiseValue :: Int32 -> RawBytes
serialiseValue Int32
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int32 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int32 -> Vector Word8) -> Int32 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int32
x

  deserialiseValue :: RawBytes -> Int32
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int32 -> Int32
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int32" Int
4 Int
len (Int32 -> Int32) -> Int32 -> Int32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int32
indexWord8ArrayAsInt32 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Int64 where
  serialiseKey :: Int64 -> RawBytes
serialiseKey Int64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int64 -> Vector Word8) -> Int64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int64 -> Int64
byteSwapInt64 Int64
x

  deserialiseKey :: RawBytes -> Int64
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int64 -> Int64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int64" Int
8 Int
len (Int64 -> Int64) -> Int64 -> Int64
forall a b. (a -> b) -> a -> b
$ Int64 -> Int64
byteSwapInt64 (ByteArray -> Int -> Int64
indexWord8ArrayAsInt64 ByteArray
ba Int
off)

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Int64 where
  serialiseValue :: Int64 -> RawBytes
serialiseValue Int64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int64 -> Vector Word8) -> Int64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int64
x

  deserialiseValue :: RawBytes -> Int64
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int64 -> Int64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int64" Int
8 Int
len (Int64 -> Int64) -> Int64 -> Int64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int64
indexWord8ArrayAsInt64 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Int where
  serialiseKey :: Int -> RawBytes
serialiseKey Int
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int -> Vector Word8) -> Int -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int
byteSwapInt Int
x

  deserialiseKey :: RawBytes -> Int
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int -> Int
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int" Int
8 Int
len (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Int
byteSwapInt (ByteArray -> Int -> Int
indexWord8ArrayAsInt ByteArray
ba Int
off)

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Int where
  serialiseValue :: Int -> RawBytes
serialiseValue Int
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Int -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Int -> Vector Word8) -> Int -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Int
x

  deserialiseValue :: RawBytes -> Int
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Int -> Int
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Int" Int
8 Int
len (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Int
indexWord8ArrayAsInt ByteArray
ba Int
off

{-------------------------------------------------------------------------------
  Word
-------------------------------------------------------------------------------}

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Word8 where
  serialiseKey :: Word8 -> RawBytes
serialiseKey Word8
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word8 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim  Word8
x

  deserialiseKey :: RawBytes -> Word8
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word8 -> Word8
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word8" Int
1 Int
len  (ByteArray -> Int -> Word8
indexWord8Array ByteArray
ba Int
off)

instance SerialiseKeyOrderPreserving Word8

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Word8 where
  serialiseValue :: Word8 -> RawBytes
serialiseValue Word8
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word8 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word8 -> Vector Word8) -> Word8 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word8
x

  deserialiseValue :: RawBytes -> Word8
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word8 -> Word8
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word8" Int
1 Int
len (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word8
indexWord8Array ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Word16 where
  serialiseKey :: Word16 -> RawBytes
serialiseKey Word16
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word16 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word16 -> Vector Word8) -> Word16 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word16 -> Word16
byteSwapWord16 Word16
x

  deserialiseKey :: RawBytes -> Word16
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word16 -> Word16
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word16" Int
2 Int
len (Word16 -> Word16) -> Word16 -> Word16
forall a b. (a -> b) -> a -> b
$ Word16 -> Word16
byteSwapWord16 (ByteArray -> Int -> Word16
indexWord8ArrayAsWord16 ByteArray
ba Int
off)

instance SerialiseKeyOrderPreserving Word16

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Word16 where
  serialiseValue :: Word16 -> RawBytes
serialiseValue Word16
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word16 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word16 -> Vector Word8) -> Word16 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word16
x

  deserialiseValue :: RawBytes -> Word16
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word16 -> Word16
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word16" Int
2 Int
len (Word16 -> Word16) -> Word16 -> Word16
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word16
indexWord8ArrayAsWord16 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Word32 where
  serialiseKey :: Word32 -> RawBytes
serialiseKey Word32
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word32 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word32 -> Vector Word8) -> Word32 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32
byteSwapWord32 Word32
x

  deserialiseKey :: RawBytes -> Word32
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word32 -> Word32
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word32" Int
4 Int
len (Word32 -> Word32) -> Word32 -> Word32
forall a b. (a -> b) -> a -> b
$ Word32 -> Word32
byteSwapWord32 (ByteArray -> Int -> Word32
indexWord8ArrayAsWord32 ByteArray
ba Int
off)

instance SerialiseKeyOrderPreserving Word32

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Word32 where
  serialiseValue :: Word32 -> RawBytes
serialiseValue Word32
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word32 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word32 -> Vector Word8) -> Word32 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word32
x

  deserialiseValue :: RawBytes -> Word32
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word32 -> Word32
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word32" Int
4 Int
len (Word32 -> Word32) -> Word32 -> Word32
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word32
indexWord8ArrayAsWord32 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Word64 where
  serialiseKey :: Word64 -> RawBytes
serialiseKey Word64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word64 -> Vector Word8) -> Word64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
byteSwapWord64 Word64
x

  deserialiseKey :: RawBytes -> Word64
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word64 -> Word64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word64" Int
8 Int
len (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ Word64 -> Word64
byteSwapWord64 (ByteArray -> Int -> Word64
indexWord8ArrayAsWord64 ByteArray
ba Int
off)

instance SerialiseKeyOrderPreserving Word64

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Word64 where
  serialiseValue :: Word64 -> RawBytes
serialiseValue Word64
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word64 -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word64 -> Vector Word8) -> Word64 -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word64
x

  deserialiseValue :: RawBytes -> Word64
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word64 -> Word64
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word64" Int
8 Int
len (Word64 -> Word64) -> Word64 -> Word64
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word64
indexWord8ArrayAsWord64 ByteArray
ba Int
off

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(1)\).
-}
instance SerialiseKey Word where
  serialiseKey :: Word -> RawBytes
serialiseKey Word
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word -> Vector Word8) -> Word -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word -> Word
byteSwapWord Word
x

  deserialiseKey :: RawBytes -> Word
deserialiseKey (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word -> Word
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word" Int
8 Int
len (Word -> Word) -> Word -> Word
forall a b. (a -> b) -> a -> b
$ Word -> Word
byteSwapWord (ByteArray -> Int -> Word
indexWord8ArrayAsWord ByteArray
ba Int
off)

instance SerialiseKeyOrderPreserving Word

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(1)\).
-}
instance SerialiseValue Word where
  serialiseValue :: Word -> RawBytes
serialiseValue Word
x = Vector Word8 -> RawBytes
RB.RawBytes (Vector Word8 -> RawBytes) -> Vector Word8 -> RawBytes
forall a b. (a -> b) -> a -> b
$ Word -> Vector Word8
forall a. Prim a => a -> Vector Word8
byteVectorFromPrim (Word -> Vector Word8) -> Word -> Vector Word8
forall a b. (a -> b) -> a -> b
$ Word
x

  deserialiseValue :: RawBytes -> Word
deserialiseValue (RawBytes (VP.Vector Int
off Int
len ByteArray
ba)) =
    String -> Int -> Int -> Word -> Word
forall a. String -> Int -> Int -> a -> a
requireBytesExactly String
"Word" Int
8 Int
len (Word -> Word) -> Word -> Word
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int -> Word
indexWord8ArrayAsWord ByteArray
ba Int
off

{-------------------------------------------------------------------------------
  String
-------------------------------------------------------------------------------}

{- |
@'serialiseKey'@: \(O(n)\).

@'deserialiseKey'@: \(O(n)\).

The 'String' is (de)serialised as UTF-8.
-}
instance SerialiseKey String where
  -- TODO: Optimise. The performance is \(O(n) + O(n)\) but it could be \(O(n)\).
  serialiseKey :: String -> RawBytes
serialiseKey = ByteString -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey (ByteString -> RawBytes)
-> (String -> ByteString) -> String -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
UTF8.fromString
  deserialiseKey :: RawBytes -> String
deserialiseKey = ByteString -> String
UTF8.toString (ByteString -> String)
-> (RawBytes -> ByteString) -> RawBytes -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteString
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey

instance SerialiseKeyOrderPreserving String

{- |
@'serialiseKey'@: \(O(n)\).

@'deserialiseKey'@: \(O(n)\).

The 'String' is (de)serialiseValue as UTF-8.
-}
instance SerialiseValue String where
  -- TODO: Optimise. The performance is \(O(n) + O(n)\) but it could be \(O(n)\).
  serialiseValue :: String -> RawBytes
serialiseValue = ByteString -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue (ByteString -> RawBytes)
-> (String -> ByteString) -> String -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
UTF8.fromString
  deserialiseValue :: RawBytes -> String
deserialiseValue = ByteString -> String
UTF8.toString (ByteString -> String)
-> (RawBytes -> ByteString) -> RawBytes -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteString
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue

{-------------------------------------------------------------------------------
  ByteString
-------------------------------------------------------------------------------}

{- |
@'serialiseKey'@: \(O(n)\).

@'deserialiseKey'@: \(O(n)\).
-}
instance SerialiseKey LBS.ByteString where
  -- TODO: Optimise. The performance is \(O(n) + O(n)\) but it could be \(O(n)\).
  serialiseKey :: ByteString -> RawBytes
serialiseKey = ByteString -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey (ByteString -> RawBytes)
-> (ByteString -> ByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict
  deserialiseKey :: RawBytes -> ByteString
deserialiseKey = Builder -> ByteString
B.toLazyByteString (Builder -> ByteString)
-> (RawBytes -> Builder) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> Builder
RB.builder

instance SerialiseKeyOrderPreserving LBS.ByteString

{- |
@'serialiseValue'@: \(O(n)\).

@'deserialiseValue'@: \(O(n)\).
-}
instance SerialiseValue LBS.ByteString where
  -- TODO: Optimise. The performance is \(O(n) + O(n)\) but it could be \(O(n)\).
  serialiseValue :: ByteString -> RawBytes
serialiseValue = ByteString -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue (ByteString -> RawBytes)
-> (ByteString -> ByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict
  deserialiseValue :: RawBytes -> ByteString
deserialiseValue = Builder -> ByteString
B.toLazyByteString (Builder -> ByteString)
-> (RawBytes -> Builder) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> Builder
RB.builder

{- |
@'serialiseKey'@: \(O(n)\).

@'deserialiseKey'@: \(O(n)\).
-}
instance SerialiseKey BS.ByteString where
  serialiseKey :: ByteString -> RawBytes
serialiseKey = ShortByteString -> RawBytes
forall k. SerialiseKey k => k -> RawBytes
serialiseKey (ShortByteString -> RawBytes)
-> (ByteString -> ShortByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort
  deserialiseKey :: RawBytes -> ByteString
deserialiseKey = ShortByteString -> ByteString
SBS.fromShort (ShortByteString -> ByteString)
-> (RawBytes -> ShortByteString) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ShortByteString
forall k. SerialiseKey k => RawBytes -> k
deserialiseKey

instance SerialiseKeyOrderPreserving BS.ByteString

{- |
@'serialiseValue'@: \(O(n)\).

@'deserialiseValue'@: \(O(n)\).
-}
instance SerialiseValue BS.ByteString where
  serialiseValue :: ByteString -> RawBytes
serialiseValue = ShortByteString -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue (ShortByteString -> RawBytes)
-> (ByteString -> ShortByteString) -> ByteString -> RawBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort
  deserialiseValue :: RawBytes -> ByteString
deserialiseValue = ShortByteString -> ByteString
SBS.fromShort (ShortByteString -> ByteString)
-> (RawBytes -> ShortByteString) -> RawBytes -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ShortByteString
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(n)\).
-}
instance SerialiseKey SBS.ShortByteString where
  serialiseKey :: ShortByteString -> RawBytes
serialiseKey = ShortByteString -> RawBytes
RB.fromShortByteString
  deserialiseKey :: RawBytes -> ShortByteString
deserialiseKey = ByteArray -> ShortByteString
byteArrayToSBS (ByteArray -> ShortByteString)
-> (RawBytes -> ByteArray) -> RawBytes -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteArray
RB.force

instance SerialiseKeyOrderPreserving SBS.ShortByteString

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(n)\).
-}
instance SerialiseValue SBS.ShortByteString where
  serialiseValue :: ShortByteString -> RawBytes
serialiseValue = ShortByteString -> RawBytes
RB.fromShortByteString
  deserialiseValue :: RawBytes -> ShortByteString
deserialiseValue = ByteArray -> ShortByteString
byteArrayToSBS (ByteArray -> ShortByteString)
-> (RawBytes -> ByteArray) -> RawBytes -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> ByteArray
RB.force

{-------------------------------------------------------------------------------
  ByteArray
-------------------------------------------------------------------------------}

{- |
@'serialiseKey'@: \(O(1)\).

@'deserialiseKey'@: \(O(n)\).
-}
instance SerialiseKey P.ByteArray where
  serialiseKey :: ByteArray -> RawBytes
serialiseKey ByteArray
ba = Int -> Int -> ByteArray -> RawBytes
RB.fromByteArray Int
0 (ByteArray -> Int
P.sizeofByteArray ByteArray
ba) ByteArray
ba
  deserialiseKey :: RawBytes -> ByteArray
deserialiseKey = RawBytes -> ByteArray
RB.force

{- |
@'serialiseValue'@: \(O(1)\).

@'deserialiseValue'@: \(O(n)\).
-}
instance SerialiseValue P.ByteArray where
  serialiseValue :: ByteArray -> RawBytes
serialiseValue ByteArray
ba = Int -> Int -> ByteArray -> RawBytes
RB.fromByteArray Int
0 (ByteArray -> Int
P.sizeofByteArray ByteArray
ba) ByteArray
ba
  deserialiseValue :: RawBytes -> ByteArray
deserialiseValue = RawBytes -> ByteArray
RB.force

{-------------------------------------------------------------------------------
  Void
-------------------------------------------------------------------------------}

{- |
This instance is intended for tables without blobs.

The implementation of 'deseriValue' throws an excepValuen.
-}
instance SerialiseValue Void where
  serialiseValue :: Void -> RawBytes
serialiseValue = Void -> RawBytes
forall a. Void -> a
absurd
  deserialiseValue :: RawBytes -> Void
deserialiseValue = String -> RawBytes -> Void
forall a. HasCallStack => String -> a
error String
"deserialiseValue: cannot deserialise into Void"

{-------------------------------------------------------------------------------
  Sum
-------------------------------------------------------------------------------}

{- |
An instance for 'Sum' which is transparent to the serialisation of the value type.

__NOTE:__ If you want to seriValue @'Sum' a@ differValuely from @a@, you must use another newtype wrapper.
-}
instance SerialiseValue a => SerialiseValue (Sum a) where
  serialiseValue :: Sum a -> RawBytes
serialiseValue (Sum a
v) = a -> RawBytes
forall v. SerialiseValue v => v -> RawBytes
serialiseValue a
v

  deserialiseValue :: RawBytes -> Sum a
deserialiseValue = a -> Sum a
forall a. a -> Sum a
Sum (a -> Sum a) -> (RawBytes -> a) -> RawBytes -> Sum a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytes -> a
forall v. SerialiseValue v => RawBytes -> v
deserialiseValue