{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
module Pinch.Internal.Value
( Value(..)
, MapItem(..)
, SomeValue(..)
, castValue
, valueTType
) where
import Control.DeepSeq (NFData (..))
import Data.ByteString (ByteString)
import Data.Hashable (Hashable (..))
import Data.HashMap.Strict (HashMap)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.List (intercalate)
import Data.Typeable ((:~:) (..), Typeable)
import qualified Data.Foldable as F
import qualified Data.HashMap.Strict as M
import qualified Data.HashSet as S
import Pinch.Internal.FoldList (FoldList)
import Pinch.Internal.TType
data MapItem k v = MapItem !(Value k) !(Value v)
deriving (MapItem k v -> MapItem k v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. MapItem k v -> MapItem k v -> Bool
/= :: MapItem k v -> MapItem k v -> Bool
$c/= :: forall k v. MapItem k v -> MapItem k v -> Bool
== :: MapItem k v -> MapItem k v -> Bool
$c== :: forall k v. MapItem k v -> MapItem k v -> Bool
Eq, Typeable)
instance NFData (MapItem k v) where
rnf :: MapItem k v -> ()
rnf (MapItem Value k
k Value v
v) = forall a. NFData a => a -> ()
rnf Value k
k seq :: forall a b. a -> b -> b
`seq` forall a. NFData a => a -> ()
rnf Value v
v seq :: forall a b. a -> b -> b
`seq` ()
instance Hashable (MapItem k v) where
hashWithSalt :: Int -> MapItem k v -> Int
hashWithSalt Int
s (MapItem Value k
k Value v
v) = Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Value k
k forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Value v
v
instance Show (MapItem k v) where
show :: MapItem k v -> String
show (MapItem Value k
k Value v
v) = forall a. Show a => a -> String
show Value k
k forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Value v
v
data Value a where
VBool :: !Bool -> Value TBool
VByte :: !Int8 -> Value TByte
VDouble :: !Double -> Value TDouble
VInt16 :: !Int16 -> Value TInt16
VInt32 :: !Int32 -> Value TInt32
VInt64 :: !Int64 -> Value TInt64
VBinary :: !ByteString -> Value TBinary
VStruct :: !(HashMap Int16 SomeValue) -> Value TStruct
VMap :: forall k v. (IsTType k, IsTType v)
=> !(FoldList (MapItem k v)) -> Value TMap
VNullMap :: Value TMap
VSet :: forall a. IsTType a => !(FoldList (Value a)) -> Value TSet
VList :: forall a. IsTType a => !(FoldList (Value a)) -> Value TList
deriving Typeable
instance Show (Value a) where
show :: Value a -> String
show (VBool Bool
x) = forall a. Show a => a -> String
show Bool
x
show (VByte Int8
x) = forall a. Show a => a -> String
show Int8
x
show (VDouble Double
x) = forall a. Show a => a -> String
show Double
x
show (VInt16 Int16
x) = String
"i16(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int16
x forall a. [a] -> [a] -> [a]
++ String
")"
show (VInt32 Int32
x) = String
"i32(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int32
x forall a. [a] -> [a] -> [a]
++ String
")"
show (VInt64 Int64
x) = String
"i64(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int64
x forall a. [a] -> [a] -> [a]
++ String
")"
show (VBinary ByteString
x) = forall a. Show a => a -> String
show ByteString
x
show (VStruct HashMap Int16 SomeValue
x) = String
"{" forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ String
"}"
where
s :: String
s = forall a. [a] -> [[a]] -> [a]
intercalate String
", " (forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
M.foldlWithKey' forall {p}. Show p => [String] -> p -> SomeValue -> [String]
go [] HashMap Int16 SomeValue
x)
go :: [String] -> p -> SomeValue -> [String]
go [String]
xs p
i (SomeValue Value a
val) = (forall a. Show a => a -> String
show p
i forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Value a
val)forall a. a -> [a] -> [a]
:[String]
xs
show (VMap FoldList (MapItem k v)
x) = forall a. Show a => a -> String
show FoldList (MapItem k v)
x
show Value a
VNullMap = String
"[]"
show (VSet FoldList (Value a)
x) = forall a. Show a => a -> String
show FoldList (Value a)
x
show (VList FoldList (Value a)
x) = forall a. Show a => a -> String
show FoldList (Value a)
x
instance Eq (Value a) where
VBool Bool
a == :: Value a -> Value a -> Bool
== VBool Bool
b = Bool
a forall a. Eq a => a -> a -> Bool
== Bool
b
VByte Int8
a == VByte Int8
b = Int8
a forall a. Eq a => a -> a -> Bool
== Int8
b
VDouble Double
a == VDouble Double
b = Double
a forall a. Eq a => a -> a -> Bool
== Double
b
VInt16 Int16
a == VInt16 Int16
b = Int16
a forall a. Eq a => a -> a -> Bool
== Int16
b
VInt32 Int32
a == VInt32 Int32
b = Int32
a forall a. Eq a => a -> a -> Bool
== Int32
b
VInt64 Int64
a == VInt64 Int64
b = Int64
a forall a. Eq a => a -> a -> Bool
== Int64
b
VBinary ByteString
a == VBinary ByteString
b = ByteString
a forall a. Eq a => a -> a -> Bool
== ByteString
b
VStruct HashMap Int16 SomeValue
a == VStruct HashMap Int16 SomeValue
b = HashMap Int16 SomeValue
a forall a. Eq a => a -> a -> Bool
== HashMap Int16 SomeValue
b
VList FoldList (Value a)
as == VList FoldList (Value a)
bs = forall a b (f :: * -> *).
(IsTType a, IsTType b, Foldable f, Eq (f (Value a))) =>
f (Value a) -> f (Value b) -> Bool
areEqual1 FoldList (Value a)
as FoldList (Value a)
bs
VMap FoldList (MapItem k v)
as == VMap FoldList (MapItem k v)
bs = forall k1 v1 k2 v2.
(IsTType k1, IsTType v1, IsTType k2, IsTType v2) =>
[(Value k1, Value v1)] -> [(Value k2, Value v2)] -> Bool
areEqual2 (forall {k} {v}. FoldList (MapItem k v) -> [(Value k, Value v)]
toMap FoldList (MapItem k v)
as) (forall {k} {v}. FoldList (MapItem k v) -> [(Value k, Value v)]
toMap FoldList (MapItem k v)
bs)
where
toMap :: FoldList (MapItem k v) -> [(Value k, Value v)]
toMap = forall k v. HashMap k v -> [(k, v)]
M.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (\HashMap (Value k) (Value v)
m (MapItem Value k
k Value v
v) -> forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
M.insert Value k
k Value v
v HashMap (Value k) (Value v)
m) forall k v. HashMap k v
M.empty
Value a
VNullMap == VMap FoldList (MapItem k v)
xs = forall a. Monoid a => a
mempty forall a. Eq a => a -> a -> Bool
== FoldList (MapItem k v)
xs
VMap FoldList (MapItem k v)
xs == Value a
VNullMap = FoldList (MapItem k v)
xs forall a. Eq a => a -> a -> Bool
== forall a. Monoid a => a
mempty
VSet FoldList (Value a)
as == VSet FoldList (Value a)
bs = forall a b (f :: * -> *).
(IsTType a, IsTType b, Foldable f, Eq (f (Value a))) =>
f (Value a) -> f (Value b) -> Bool
areEqual1 (forall (f :: * -> *) x.
(Foldable f, Hashable x, Eq x) =>
f x -> HashSet x
toSet FoldList (Value a)
as) (forall (f :: * -> *) x.
(Foldable f, Hashable x, Eq x) =>
f x -> HashSet x
toSet FoldList (Value a)
bs)
Value a
_ == Value a
_ = Bool
False
toSet :: forall f x. (F.Foldable f, Hashable x, Eq x) => f x -> S.HashSet x
toSet :: forall (f :: * -> *) x.
(Foldable f, Hashable x, Eq x) =>
f x -> HashSet x
toSet = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
S.insert) forall a. HashSet a
S.empty
instance NFData (Value a) where
rnf :: Value a -> ()
rnf (VBool Bool
a) = forall a. NFData a => a -> ()
rnf Bool
a
rnf (VByte Int8
a) = forall a. NFData a => a -> ()
rnf Int8
a
rnf (VDouble Double
a) = forall a. NFData a => a -> ()
rnf Double
a
rnf (VInt16 Int16
a) = forall a. NFData a => a -> ()
rnf Int16
a
rnf (VInt32 Int32
a) = forall a. NFData a => a -> ()
rnf Int32
a
rnf (VInt64 Int64
a) = forall a. NFData a => a -> ()
rnf Int64
a
rnf (VBinary ByteString
a) = forall a. NFData a => a -> ()
rnf ByteString
a
rnf (VStruct HashMap Int16 SomeValue
a) = forall a. NFData a => a -> ()
rnf HashMap Int16 SomeValue
a
rnf (VMap FoldList (MapItem k v)
as) = forall a. NFData a => a -> ()
rnf FoldList (MapItem k v)
as
rnf Value a
VNullMap = ()
rnf (VSet FoldList (Value a)
as) = forall a. NFData a => a -> ()
rnf FoldList (Value a)
as
rnf (VList FoldList (Value a)
as) = forall a. NFData a => a -> ()
rnf FoldList (Value a)
as
data SomeValue where
SomeValue :: (IsTType a) => !(Value a) -> SomeValue
deriving Typeable
deriving instance Show SomeValue
instance Eq SomeValue where
SomeValue Value a
a == :: SomeValue -> SomeValue -> Bool
== SomeValue Value a
b = forall a b. (IsTType a, IsTType b) => Value a -> Value b -> Bool
areEqual Value a
a Value a
b
instance NFData SomeValue where
rnf :: SomeValue -> ()
rnf (SomeValue Value a
a) = forall a. NFData a => a -> ()
rnf Value a
a
castValue :: forall a b. (IsTType a, IsTType b) => Value a -> Maybe (Value b)
castValue :: forall a b. (IsTType a, IsTType b) => Value a -> Maybe (Value b)
castValue Value a
v = case forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT :: Maybe (a :~: b) of
Just a :~: b
Refl -> forall a. a -> Maybe a
Just Value a
v
Maybe (a :~: b)
Nothing -> forall a. Maybe a
Nothing
{-# INLINE castValue #-}
valueTType :: IsTType a => Value a -> TType a
valueTType :: forall a. IsTType a => Value a -> TType a
valueTType Value a
_ = forall a. IsTType a => TType a
ttype
{-# INLINE valueTType #-}
areEqual
:: forall a b. (IsTType a, IsTType b) => Value a -> Value b -> Bool
areEqual :: forall a b. (IsTType a, IsTType b) => Value a -> Value b -> Bool
areEqual Value a
l Value b
r = case forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT :: Maybe (a :~: b) of
Just a :~: b
Refl -> Value a
l forall a. Eq a => a -> a -> Bool
== Value b
r
Maybe (a :~: b)
Nothing -> Bool
False
{-# INLINE areEqual #-}
areEqual1
:: forall a b f. (IsTType a, IsTType b, F.Foldable f, Eq (f (Value a)))
=> f (Value a) -> f (Value b) -> Bool
areEqual1 :: forall a b (f :: * -> *).
(IsTType a, IsTType b, Foldable f, Eq (f (Value a))) =>
f (Value a) -> f (Value b) -> Bool
areEqual1 f (Value a)
l f (Value b)
r = case forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT of
Just (a :~: b
Refl :: a :~: b) -> f (Value a)
l forall a. Eq a => a -> a -> Bool
== f (Value b)
r
Maybe (a :~: b)
Nothing -> Bool
False
{-# INLINE areEqual1 #-}
areEqual2
:: forall k1 v1 k2 v2.
( IsTType k1, IsTType v1, IsTType k2, IsTType v2
) => [(Value k1, Value v1)] -> [(Value k2, Value v2)] -> Bool
areEqual2 :: forall k1 v1 k2 v2.
(IsTType k1, IsTType v1, IsTType k2, IsTType v2) =>
[(Value k1, Value v1)] -> [(Value k2, Value v2)] -> Bool
areEqual2 [(Value k1, Value v1)]
l [(Value k2, Value v2)]
r = case forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT of
Just (k1 :~: k2
Refl :: k1 :~: k2) -> case forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT of
Just (v1 :~: v2
Refl :: v1 :~: v2) -> [(Value k1, Value v1)]
l forall a. Eq a => a -> a -> Bool
== [(Value k2, Value v2)]
r
Maybe (v1 :~: v2)
Nothing -> Bool
False
Maybe (k1 :~: k2)
Nothing -> Bool
False
{-# INLINE areEqual2 #-}
instance Hashable (Value a) where
hashWithSalt :: Int -> Value a -> Int
hashWithSalt Int
s Value a
a = case Value a
a of
VBinary ByteString
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
0 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` ByteString
x
VBool Bool
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
1 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Bool
x
VByte Int8
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
2 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int8
x
VDouble Double
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
3 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Double
x
VInt16 Int16
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
4 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int16
x
VInt32 Int32
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
5 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int32
x
VInt64 Int64
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
6 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int64
x
VList FoldList (Value a)
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
7 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` FoldList (Value a)
x
VMap FoldList (MapItem k v)
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
8 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` FoldList (MapItem k v)
x
Value a
VNullMap -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
8 :: Int)
VSet FoldList (Value a)
x -> Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
9 :: Int) forall a. Hashable a => Int -> a -> Int
`hashWithSalt` FoldList (Value a)
x
VStruct HashMap Int16 SomeValue
fields ->
forall a k v. (a -> k -> v -> a) -> a -> HashMap k v -> a
M.foldlWithKey' (\Int
s' Int16
k SomeValue
v -> Int
s' forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int16
k forall a. Hashable a => Int -> a -> Int
`hashWithSalt` SomeValue
v)
(Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
10 :: Int))
HashMap Int16 SomeValue
fields
instance Hashable SomeValue where
hashWithSalt :: Int -> SomeValue -> Int
hashWithSalt Int
s (SomeValue Value a
v) = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
s Value a
v