packages feed

keiro-dsl-0.21.0.0: test/conformance-mapped-register-construction/Generated/MappedRegisterConstruction/Lifecycle/Codec.hs

-- @generated by keiro-dsl 0.21.0.0 (language keiro-dsl 6) from aggregate Lifecycle; do not edit.
module Generated.MappedRegisterConstruction.Lifecycle.Codec (
    lifecycleCodec,
    parseLifecycleEvent,
    encodeLifecycleEvent,
) where

import Generated.MappedRegisterConstruction.Lifecycle.Domain
import Data.Aeson (Value, object, withObject, (.:), (.=))
import Data.Aeson.Types (parseEither)
import Data.List.NonEmpty (NonEmpty (..))
import Data.List.NonEmpty qualified as NonEmpty
import Data.Text (Text)
import qualified Data.Text as T
import Keiro.Codec (Codec (..), EventType (..))





lifecycleEventTypes :: NonEmpty EventType
lifecycleEventTypes = EventType "Created" :| [EventType "Marked", EventType "Pinged", EventType "Awakened", EventType "ClosedEvent", EventType "Reopened"]

lifecycleCodec :: Codec LifecycleEvent
lifecycleCodec =
  Codec
    { eventTypes = lifecycleEventTypes
    , eventType = \case
        Created{} -> EventType "Created"
        Marked{} -> EventType "Marked"
        Pinged{} -> EventType "Pinged"
        Awakened{} -> EventType "Awakened"
        ClosedEvent{} -> EventType "ClosedEvent"
        Reopened{} -> EventType "Reopened"
    , schemaVersion = 1
    , encode = encodeLifecycleEvent
    , decode = parseLifecycleEvent
    , upcasters = []
    }

encodeLifecycleEvent :: LifecycleEvent -> Value
encodeLifecycleEvent = \case
  Created payload ->
    object
      [ "kind" .= ("Created" :: Text)
      , "automatic" .= payload.automatic
      ]
  Marked payload ->
    object
      [ "kind" .= ("Marked" :: Text)
      , "markedAt" .= payload.markedAt
      ]
  Pinged payload ->
    object
      [ "kind" .= ("Pinged" :: Text)
      , "markedAt" .= payload.markedAt
      ]
  Awakened payload ->
    object
      [ "kind" .= ("Awakened" :: Text)
      , "awakenedAt" .= payload.awakenedAt
      ]
  ClosedEvent payload ->
    object
      [ "kind" .= ("ClosedEvent" :: Text)
      , "closedAt" .= payload.closedAt
      ]
  Reopened payload ->
    object
      [ "kind" .= ("Reopened" :: Text)
      , "reopenedAt" .= payload.reopenedAt
      ]

parseLifecycleEvent :: EventType -> Value -> Either Text LifecycleEvent
parseLifecycleEvent (EventType tag) = mapLeftText . parseEither (withObject "LifecycleEvent" go)
  where
    go o = do
      case tag of
        "Created" ->
          Created
            <$> ( CreatedData
                    <$> o .: "automatic"
                )
        "Marked" ->
          Marked
            <$> ( MarkedData
                    <$> o .: "markedAt"
                )
        "Pinged" ->
          Pinged
            <$> ( PingedData
                    <$> o .: "markedAt"
                )
        "Awakened" ->
          Awakened
            <$> ( AwakenedData
                    <$> o .: "awakenedAt"
                )
        "ClosedEvent" ->
          ClosedEvent
            <$> ( ClosedEventData
                    <$> o .: "closedAt"
                )
        "Reopened" ->
          Reopened
            <$> ( ReopenedData
                    <$> o .: "reopenedAt"
                )
        _ -> fail ("unknown event type " <> show tag <> "; expected one of: " <> renderExpectedEventTypes lifecycleEventTypes)

mapLeftText :: Either String b -> Either Text b
mapLeftText = either (Left . T.pack) Right

renderExpectedEventTypes :: NonEmpty EventType -> String
renderExpectedEventTypes =
  T.unpack
    . T.intercalate ", "
    . map (\(EventType eventTypeName) -> eventTypeName)
    . NonEmpty.toList