streamly-core-0.2.0: src/Streamly/Internal/Data/Serialize/TH/Common.hs
{-# LANGUAGE TemplateHaskell #-}
-- |
-- Module : Streamly.Internal.Data.Serialize.TH.Common
-- Copyright : (c) 2023 Composewell Technologies
-- License : BSD3-3-Clause
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
--
module Streamly.Internal.Data.Serialize.TH.Common
( mkDeserializeExprOne
, mkSerializeExprFields
) where
--------------------------------------------------------------------------------
-- Imports
--------------------------------------------------------------------------------
import Language.Haskell.TH
import Streamly.Internal.Data.Serialize.TH.Bottom
--------------------------------------------------------------------------------
-- Code
--------------------------------------------------------------------------------
mkDeserializeExprOne :: Name -> SimpleDataCon -> Q Exp
mkDeserializeExprOne peeker (SimpleDataCon cname fields) =
case fields of
-- Only tag is serialized for unit fields, no actual value
[] -> [|pure ($(varE (mkName "i0")), $(conE cname))|]
_ ->
doE
(concat
[ fmap makeBind [0 .. (numFields - 1)]
, [ noBindS
(appE
(varE 'pure)
(tupE
[ varE (makeI numFields)
, appsE
(conE cname :
(map (varE . makeA)
[0 .. (numFields - 1)]))
]))
]
])
where
numFields = length fields
makeBind i =
bindS
(tupP [varP (makeI (i + 1)), varP (makeA i)])
[|$(varE peeker) $(varE (makeI i)) $(varE _arr) $(varE _endOffset)|]
mkSerializeExprFields :: Name -> [Field] -> Q Exp
mkSerializeExprFields poker fields =
case fields of
-- Unit constructor, do nothing just tag is enough
[] -> [|pure ($(varE (mkName "i0")))|]
_ ->
doE
(fmap makeBind [0 .. (numFields - 1)] ++
[noBindS ([|pure $(varE (makeI numFields))|])])
where
numFields = length fields
makeBind i =
bindS
(varP (makeI (i + 1)))
[|$(varE poker)
$(varE (makeI i)) $(varE _arr) $(varE (mkFieldName i))|]