{-# language BangPatterns #-}
{-# language DuplicateRecordFields #-}
{-# language NamedFieldPuns #-}
{-# language DerivingStrategies #-}

module Kafka.Header.Response.V1
  ( Header(..)
  , Headed(..)
  , parser
  , decode
  ) where

import Data.Primitive (SmallArray)
import Data.Int (Int32)
import Kafka.Parser.Context (Context)
import Data.Bytes.Parser (Parser)
import Data.Bytes (Bytes)
import Kafka.TaggedField (TaggedField)

import qualified Data.Bytes.Parser as Parser
import qualified Kafka.Parser.Context as Ctx
import qualified Kafka.TaggedField as TaggedField
import qualified Kafka.Parser

data Headed a = Headed
  { forall a. Headed a -> Header
header :: !Header
  , forall a. Headed a -> a
response :: !a
  } deriving stock (Int -> Headed a -> ShowS
[Headed a] -> ShowS
Headed a -> String
(Int -> Headed a -> ShowS)
-> (Headed a -> String) -> ([Headed a] -> ShowS) -> Show (Headed a)
forall a. Show a => Int -> Headed a -> ShowS
forall a. Show a => [Headed a] -> ShowS
forall a. Show a => Headed a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Headed a -> ShowS
showsPrec :: Int -> Headed a -> ShowS
$cshow :: forall a. Show a => Headed a -> String
show :: Headed a -> String
$cshowList :: forall a. Show a => [Headed a] -> ShowS
showList :: [Headed a] -> ShowS
Show)

data Header = Header
  { Header -> Int32
correlationId :: !Int32
  , Header -> SmallArray TaggedField
taggedFields :: !(SmallArray TaggedField)
  } deriving (Int -> Header -> ShowS
[Header] -> ShowS
Header -> String
(Int -> Header -> ShowS)
-> (Header -> String) -> ([Header] -> ShowS) -> Show Header
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Header -> ShowS
showsPrec :: Int -> Header -> ShowS
$cshow :: Header -> String
show :: Header -> String
$cshowList :: [Header] -> ShowS
showList :: [Header] -> ShowS
Show)

-- | Note: Decode is here for the benefit of the test suite. A response
-- header prefaces another message, so in an actual kafka client,
-- it makes more sense to monadically sequence the two parsers.
decode :: Bytes -> Either Context Header
decode :: Bytes -> Either Context Header
decode !Bytes
b = (forall s. Parser Context s Header)
-> Bytes -> Either Context Header
forall e a. (forall s. Parser e s a) -> Bytes -> Either e a
Parser.parseBytesEither (Context -> Parser Context s Header
forall s. Context -> Parser Context s Header
parser Context
Ctx.Top Parser Context s Header
-> Parser Context s () -> Parser Context s Header
forall a b.
Parser Context s a -> Parser Context s b -> Parser Context s a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Context -> Parser Context s ()
forall e s. e -> Parser e s ()
Parser.endOfInput Context
Ctx.End) Bytes
b

parser :: Context -> Parser Context s Header
parser :: forall s. Context -> Parser Context s Header
parser Context
ctx = do
  Int32
correlationId <- Context -> Parser Context s Int32
forall e s. e -> Parser e s Int32
Kafka.Parser.int32 (Field -> Context -> Context
Ctx.Field Field
Ctx.CorrelationId Context
ctx)
  SmallArray TaggedField
taggedFields <- Context -> Parser Context s (SmallArray TaggedField)
forall s. Context -> Parser Context s (SmallArray TaggedField)
TaggedField.parserMany (Field -> Context -> Context
Ctx.Field Field
Ctx.TagBuffer Context
ctx)
  Header -> Parser Context s Header
forall a. a -> Parser Context s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Header{Int32
$sel:correlationId:Header :: Int32
correlationId :: Int32
correlationId,SmallArray TaggedField
$sel:taggedFields:Header :: SmallArray TaggedField
taggedFields :: SmallArray TaggedField
taggedFields}