module Rattletrap.Type.CompressedWordVector where

import qualified Rattletrap.BitGet as BitGet
import qualified Rattletrap.BitPut as BitPut
import qualified Rattletrap.Schema as Schema
import qualified Rattletrap.Type.CompressedWord as CompressedWord
import qualified Rattletrap.Utility.Json as Json

data CompressedWordVector = CompressedWordVector
  { CompressedWordVector -> CompressedWord
x :: CompressedWord.CompressedWord,
    CompressedWordVector -> CompressedWord
y :: CompressedWord.CompressedWord,
    CompressedWordVector -> CompressedWord
z :: CompressedWord.CompressedWord
  }
  deriving (CompressedWordVector -> CompressedWordVector -> Bool
(CompressedWordVector -> CompressedWordVector -> Bool)
-> (CompressedWordVector -> CompressedWordVector -> Bool)
-> Eq CompressedWordVector
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CompressedWordVector -> CompressedWordVector -> Bool
== :: CompressedWordVector -> CompressedWordVector -> Bool
$c/= :: CompressedWordVector -> CompressedWordVector -> Bool
/= :: CompressedWordVector -> CompressedWordVector -> Bool
Eq, Int -> CompressedWordVector -> ShowS
[CompressedWordVector] -> ShowS
CompressedWordVector -> String
(Int -> CompressedWordVector -> ShowS)
-> (CompressedWordVector -> String)
-> ([CompressedWordVector] -> ShowS)
-> Show CompressedWordVector
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CompressedWordVector -> ShowS
showsPrec :: Int -> CompressedWordVector -> ShowS
$cshow :: CompressedWordVector -> String
show :: CompressedWordVector -> String
$cshowList :: [CompressedWordVector] -> ShowS
showList :: [CompressedWordVector] -> ShowS
Show)

instance Json.FromJSON CompressedWordVector where
  parseJSON :: Value -> Parser CompressedWordVector
parseJSON = String
-> (Object -> Parser CompressedWordVector)
-> Value
-> Parser CompressedWordVector
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"CompressedWordVector" ((Object -> Parser CompressedWordVector)
 -> Value -> Parser CompressedWordVector)
-> (Object -> Parser CompressedWordVector)
-> Value
-> Parser CompressedWordVector
forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    CompressedWord
x <- Object -> String -> Parser CompressedWord
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"x"
    CompressedWord
y <- Object -> String -> Parser CompressedWord
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"y"
    CompressedWord
z <- Object -> String -> Parser CompressedWord
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"z"
    CompressedWordVector -> Parser CompressedWordVector
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CompressedWordVector {CompressedWord
x :: CompressedWord
x :: CompressedWord
x, CompressedWord
y :: CompressedWord
y :: CompressedWord
y, CompressedWord
z :: CompressedWord
z :: CompressedWord
z}

instance Json.ToJSON CompressedWordVector where
  toJSON :: CompressedWordVector -> Value
toJSON CompressedWordVector
a =
    [(Key, Value)] -> Value
Json.object [String -> CompressedWord -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"x" (CompressedWord -> (Key, Value)) -> CompressedWord -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ CompressedWordVector -> CompressedWord
x CompressedWordVector
a, String -> CompressedWord -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"y" (CompressedWord -> (Key, Value)) -> CompressedWord -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ CompressedWordVector -> CompressedWord
y CompressedWordVector
a, String -> CompressedWord -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"z" (CompressedWord -> (Key, Value)) -> CompressedWord -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ CompressedWordVector -> CompressedWord
z CompressedWordVector
a]

schema :: Schema.Schema
schema :: Schema
schema =
  String -> Value -> Schema
Schema.named String
"compressed-word-vector" (Value -> Schema) -> Value -> Schema
forall a b. (a -> b) -> a -> b
$
    [((Key, Value), Bool)] -> Value
Schema.object
      [ (String -> Value -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"x" (Value -> (Key, Value)) -> Value -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
CompressedWord.schema, Bool
True),
        (String -> Value -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"y" (Value -> (Key, Value)) -> Value -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
CompressedWord.schema, Bool
True),
        (String -> Value -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"z" (Value -> (Key, Value)) -> Value -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
CompressedWord.schema, Bool
True)
      ]

bitPut :: CompressedWordVector -> BitPut.BitPut
bitPut :: CompressedWordVector -> BitPut
bitPut CompressedWordVector
compressedWordVector =
  CompressedWord -> BitPut
CompressedWord.bitPut (CompressedWordVector -> CompressedWord
x CompressedWordVector
compressedWordVector)
    BitPut -> BitPut -> BitPut
forall a. Semigroup a => a -> a -> a
<> CompressedWord -> BitPut
CompressedWord.bitPut (CompressedWordVector -> CompressedWord
y CompressedWordVector
compressedWordVector)
    BitPut -> BitPut -> BitPut
forall a. Semigroup a => a -> a -> a
<> CompressedWord -> BitPut
CompressedWord.bitPut (CompressedWordVector -> CompressedWord
z CompressedWordVector
compressedWordVector)

bitGet :: BitGet.BitGet CompressedWordVector
bitGet :: BitGet CompressedWordVector
bitGet = do
  CompressedWord
x <- Word -> BitGet CompressedWord
CompressedWord.bitGet Word
limit
  CompressedWord
y <- Word -> BitGet CompressedWord
CompressedWord.bitGet Word
limit
  CompressedWord
z <- Word -> BitGet CompressedWord
CompressedWord.bitGet Word
limit
  CompressedWordVector -> BitGet CompressedWordVector
forall a. a -> Get BitString Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CompressedWordVector {CompressedWord
x :: CompressedWord
x :: CompressedWord
x, CompressedWord
y :: CompressedWord
y :: CompressedWord
y, CompressedWord
z :: CompressedWord
z :: CompressedWord
z}

limit :: Word
limit :: Word
limit = Word
65536