module DomainAeson.InstanceDecs where

import DomainAeson.Prelude
import qualified DomainAeson.Util.AesonTH as AesonTH
import qualified DomainCore.Model as Model
import qualified DomainCore.TH as DomainTH
import Language.Haskell.TH.Syntax
import THLego.Helpers

toJson :: Model.TypeDec -> [Dec]
toJson :: TypeDec -> [Dec]
toJson (Model.TypeDec Text
typeName TypeDef
typeDef) =
  Dec -> [Dec]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Dec -> [Dec]) -> Dec -> [Dec]
forall a b. (a -> b) -> a -> b
$ case TypeDef
typeDef of
    Model.ProductTypeDef [(Text, Type)]
members ->
      Type -> Name -> [Text] -> Dec
AesonTH.productToJsonInstanceDec
        (Name -> Type
ConT (Text -> Name
textName Text
typeName))
        (Text -> Name
textName Text
typeName)
        (((Text, Type) -> Text) -> [(Text, Type)] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text, Type) -> Text
forall a b. (a, b) -> a
fst [(Text, Type)]
members)
    Model.SumTypeDef [(Text, [Type])]
members ->
      Type -> [(Text, Name, Int)] -> Dec
AesonTH.sumToJsonInstanceDec
        (Name -> Type
ConT (Text -> Name
textName Text
typeName))
        (((Text, [Type]) -> (Text, Name, Int))
-> [(Text, [Type])] -> [(Text, Name, Int)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text, [Type]) -> (Text, Name, Int)
member [(Text, [Type])]
members)
      where
        member :: (Text, [Type]) -> (Text, Name, Int)
member (Text
memberName, [Type]
memberComponentTypes) =
          ( Text
memberName,
            Text -> Text -> Name
DomainTH.sumConstructorName Text
typeName Text
memberName,
            [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
memberComponentTypes
          )