module Rattletrap.Type.Message where

import qualified Rattletrap.ByteGet as ByteGet
import qualified Rattletrap.BytePut as BytePut
import qualified Rattletrap.Schema as Schema
import qualified Rattletrap.Type.Str as Str
import qualified Rattletrap.Type.U32 as U32
import qualified Rattletrap.Utility.Json as Json

data Message = Message
  { Message -> U32
frame :: U32.U32
  -- ^ Which frame this message belongs to, starting from 0.
  , Message -> Str
name :: Str.Str
  -- ^ The primary player's name.
  , Message -> Str
value :: Str.Str
  -- ^ The content of the message.
  }
  deriving (Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c== :: Message -> Message -> Bool
Eq, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
(Int -> Message -> ShowS)
-> (Message -> String) -> ([Message] -> ShowS) -> Show Message
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Message] -> ShowS
$cshowList :: [Message] -> ShowS
show :: Message -> String
$cshow :: Message -> String
showsPrec :: Int -> Message -> ShowS
$cshowsPrec :: Int -> Message -> ShowS
Show)

instance Json.FromJSON Message where
  parseJSON :: Value -> Parser Message
parseJSON = String -> (Object -> Parser Message) -> Value -> Parser Message
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"Message" ((Object -> Parser Message) -> Value -> Parser Message)
-> (Object -> Parser Message) -> Value -> Parser Message
forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    U32
frame <- Object -> String -> Parser U32
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"frame"
    Str
name <- Object -> String -> Parser Str
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"name"
    Str
value <- Object -> String -> Parser Str
forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"value"
    Message -> Parser Message
forall (f :: * -> *) a. Applicative f => a -> f a
pure Message :: U32 -> Str -> Str -> Message
Message { U32
frame :: U32
frame :: U32
frame, Str
name :: Str
name :: Str
name, Str
value :: Str
value :: Str
value }

instance Json.ToJSON Message where
  toJSON :: Message -> Value
toJSON Message
x = [Pair] -> Value
Json.object
    [ String -> U32 -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"frame" (U32 -> Pair) -> U32 -> Pair
forall a b. (a -> b) -> a -> b
$ Message -> U32
frame Message
x
    , String -> Str -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"name" (Str -> Pair) -> Str -> Pair
forall a b. (a -> b) -> a -> b
$ Message -> Str
name Message
x
    , String -> Str -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"value" (Str -> Pair) -> Str -> Pair
forall a b. (a -> b) -> a -> b
$ Message -> Str
value Message
x
    ]

schema :: Schema.Schema
schema :: Schema
schema = String -> Value -> Schema
Schema.named String
"message" (Value -> Schema) -> Value -> Schema
forall a b. (a -> b) -> a -> b
$ [(Pair, Bool)] -> Value
Schema.object
  [ (String -> Value -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"frame" (Value -> Pair) -> Value -> Pair
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
U32.schema, Bool
True)
  , (String -> Value -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"name" (Value -> Pair) -> Value -> Pair
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
Str.schema, Bool
True)
  , (String -> Value -> Pair
forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"value" (Value -> Pair) -> Value -> Pair
forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
Str.schema, Bool
True)
  ]

bytePut :: Message -> BytePut.BytePut
bytePut :: Message -> BytePut
bytePut Message
x =
  U32 -> BytePut
U32.bytePut (Message -> U32
frame Message
x) BytePut -> BytePut -> BytePut
forall a. Semigroup a => a -> a -> a
<> Str -> BytePut
Str.bytePut (Message -> Str
name Message
x) BytePut -> BytePut -> BytePut
forall a. Semigroup a => a -> a -> a
<> Str -> BytePut
Str.bytePut (Message -> Str
value Message
x)

byteGet :: ByteGet.ByteGet Message
byteGet :: ByteGet Message
byteGet = do
  U32
frame <- ByteGet U32
U32.byteGet
  Str
name <- ByteGet Str
Str.byteGet
  Str
value <- ByteGet Str
Str.byteGet
  Message -> ByteGet Message
forall (f :: * -> *) a. Applicative f => a -> f a
pure Message :: U32 -> Str -> Str -> Message
Message { U32
frame :: U32
frame :: U32
frame, Str
name :: Str
name :: Str
name, Str
value :: Str
value :: Str
value }