module Database.Bolt.Value.Helpers where

import           Control.Applicative (liftA2, liftA3, pure)
import           Data.Bits           ((.&.))
import           Data.Word           (Word8, Word32)

-- = Checkers

isTinyInt :: Integral a => a -> Bool
isTinyInt :: a -> Bool
isTinyInt = (a, a) -> a -> Bool
forall a. Ord a => (a, a) -> a -> Bool
inRange (-a
16, a
128 a -> a -> a
forall a. Num a => a -> a -> a
- a
1)

isTinyWord :: Word8 -> Bool
isTinyWord :: Word8 -> Bool
isTinyWord = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
textConst) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
240)

isTinyText :: Word8 -> Bool
isTinyText :: Word8 -> Bool
isTinyText = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
textConst) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
listConst)

isTinyList :: Word8 -> Bool
isTinyList :: Word8 -> Bool
isTinyList = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
listConst) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
dictConst)

isTinyDict :: Word8 -> Bool
isTinyDict :: Word8 -> Bool
isTinyDict = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
dictConst) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
structConst)

isTinyStruct :: Word8 -> Bool
isTinyStruct :: Word8 -> Bool
isTinyStruct = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
structConst) (Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Word8
nullCode)

isNull :: Word8 -> Bool
isNull :: Word8 -> Bool
isNull = (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
nullCode)

isBool :: Word8 -> Bool
isBool :: Word8 -> Bool
isBool = (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
trueCode) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
falseCode)

isInt :: Word8 -> Bool
isInt :: Word8 -> Bool
isInt = do Bool
x <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
int8Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
int16Code)
           Bool
y <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
int32Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
int64Code)
           Bool
z <- Word8 -> Bool
isTinyWord
           Bool -> Word8 -> Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Word8 -> Bool) -> Bool -> Word8 -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
x Bool -> Bool -> Bool
|| Bool
y Bool -> Bool -> Bool
|| Bool
z

isDouble :: Word8 -> Bool
isDouble :: Word8 -> Bool
isDouble = (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
doubleCode)

isDict :: Word8 -> Bool
isDict :: Word8 -> Bool
isDict = do Bool
x <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
dict8Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
dict16Code)
            Bool
y <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
dict32Code) Word8 -> Bool
isTinyDict
            Bool -> Word8 -> Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Word8 -> Bool) -> Bool -> Word8 -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
x Bool -> Bool -> Bool
|| Bool
y

isText :: Word8 -> Bool
isText :: Word8 -> Bool
isText = do Bool
x <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
text8Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
text16Code)
            Bool
y <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
text32Code) Word8 -> Bool
isTinyText
            Bool -> Word8 -> Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Word8 -> Bool) -> Bool -> Word8 -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
x Bool -> Bool -> Bool
|| Bool
y

isList :: Word8 -> Bool
isList :: Word8 -> Bool
isList = do Bool
x <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
list8Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
list16Code)
            Bool
y <- (Bool -> Bool -> Bool)
-> (Word8 -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
list32Code) Word8 -> Bool
isTinyList
            Bool -> Word8 -> Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Word8 -> Bool) -> Bool -> Word8 -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
x Bool -> Bool -> Bool
|| Bool
y

isStruct :: Word8 -> Bool
isStruct :: Word8 -> Bool
isStruct = (Bool -> Bool -> Bool -> Bool)
-> (Word8 -> Bool)
-> (Word8 -> Bool)
-> (Word8 -> Bool)
-> Word8
-> Bool
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 (\Bool
x Bool
y Bool
z -> Bool
x Bool -> Bool -> Bool
|| Bool
y Bool -> Bool -> Bool
|| Bool
z) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
struct8Code) (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
struct16Code) Word8 -> Bool
isTinyStruct

isNewVersion :: Word32 -> Bool
isNewVersion :: Word32 -> Bool
isNewVersion Word32
v = (Word32
v Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
255) Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
3

-- = Constants

-- == Null

nullCode :: Word8
nullCode :: Word8
nullCode = Word8
192

-- == Bool

falseCode :: Word8
falseCode :: Word8
falseCode = Word8
194

trueCode :: Word8
trueCode :: Word8
trueCode = Word8
195

-- == Numbers

int8Code :: Word8
int8Code :: Word8
int8Code = Word8
200

int16Code :: Word8
int16Code :: Word8
int16Code = Word8
201

int32Code :: Word8
int32Code :: Word8
int32Code = Word8
202

int64Code :: Word8
int64Code :: Word8
int64Code = Word8
203

doubleCode :: Word8
doubleCode :: Word8
doubleCode = Word8
193

-- == Text

textConst :: Word8
textConst :: Word8
textConst = Word8
128

text8Code :: Word8
text8Code :: Word8
text8Code = Word8
208

text16Code :: Word8
text16Code :: Word8
text16Code = Word8
209

text32Code :: Word8
text32Code :: Word8
text32Code = Word8
210

-- == List

listConst :: Word8
listConst :: Word8
listConst = Word8
144

list8Code :: Word8
list8Code :: Word8
list8Code = Word8
212

list16Code :: Word8
list16Code :: Word8
list16Code = Word8
213

list32Code :: Word8
list32Code :: Word8
list32Code = Word8
214

-- == Dict

dictConst :: Word8
dictConst :: Word8
dictConst = Word8
160

dict8Code :: Word8
dict8Code :: Word8
dict8Code = Word8
216

dict16Code :: Word8
dict16Code :: Word8
dict16Code = Word8
217

dict32Code :: Word8
dict32Code :: Word8
dict32Code = Word8
218

-- == Structure

structConst :: Word8
structConst :: Word8
structConst = Word8
176

struct8Code :: Word8
struct8Code :: Word8
struct8Code = Word8
220

struct16Code :: Word8
struct16Code :: Word8
struct16Code = Word8
221

-- == Neo4j subject signatures

sigNode :: Word8
sigNode :: Word8
sigNode = Word8
78

sigRel :: Word8
sigRel :: Word8
sigRel = Word8
82

sigURel :: Word8
sigURel :: Word8
sigURel = Word8
114

sigPath :: Word8
sigPath :: Word8
sigPath = Word8
80

-- == BOLT requests signatures

sigInit :: Word8
sigInit :: Word8
sigInit = Word8
1

sigRun :: Word8
sigRun :: Word8
sigRun = Word8
16

sigAFail :: Word8
sigAFail :: Word8
sigAFail = Word8
14

sigReset :: Word8
sigReset :: Word8
sigReset = Word8
15

sigDAll :: Word8
sigDAll :: Word8
sigDAll = Word8
47

sigPAll :: Word8
sigPAll :: Word8
sigPAll = Word8
63

sigGBye :: Word8 
sigGBye :: Word8
sigGBye = Word8
2

-- == BOLT responses signatures

sigSucc :: Word8
sigSucc :: Word8
sigSucc = Word8
112

sigFail :: Word8
sigFail :: Word8
sigFail = Word8
127

sigRecs :: Word8
sigRecs :: Word8
sigRecs = Word8
113

sigIgn :: Word8
sigIgn :: Word8
sigIgn = Word8
126

-- = Other helpers

toInt :: Integral a => a -> Int
toInt :: a -> Int
toInt = a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral

getSize :: Word8 -> Int
getSize :: Word8 -> Int
getSize Word8
x = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Int) -> Word8 -> Int
forall a b. (a -> b) -> a -> b
$ Word8
x Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
15

inRange :: Ord a => (a, a) -> a -> Bool
inRange :: (a, a) -> a -> Bool
inRange (a
low, a
up) a
x = a
low a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
x Bool -> Bool -> Bool
&& a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
up

isIntX :: Integral x => x -> x -> Bool
isIntX :: x -> x -> Bool
isIntX x
p = (x, x) -> x -> Bool
forall a. Ord a => (a, a) -> a -> Bool
inRange (-x
2x -> x -> x
forall a b. (Num a, Integral b) => a -> b -> a
^(x
px -> x -> x
forall a. Num a => a -> a -> a
-x
1), x
2x -> x -> x
forall a b. (Num a, Integral b) => a -> b -> a
^(x
px -> x -> x
forall a. Num a => a -> a -> a
-x
1) x -> x -> x
forall a. Num a => a -> a -> a
- x
1)