keiro-dsl-0.18.0.0: test/conformance-structural-text-sets/Generated/StructuralTextSets/LabelStore/Codec.hs
-- @generated by keiro-dsl 0.18.0.0 (language keiro-dsl 6) from aggregate LabelStore; do not edit.
module Generated.StructuralTextSets.LabelStore.Codec (
labelStoreCodec,
parseLabelStoreEvent,
encodeLabelStoreEvent,
encodeLabelEnvelopeMapped,
decodeLabelEnvelopeMapped,
encodeMaybeTextLabelsMapped,
decodeMaybeTextLabelsMapped,
encodeTextLabelsMapped,
decodeTextLabelsMapped,
) where
import Generated.StructuralTextSets.LabelStore.Domain
import Control.Monad (unless)
import Data.Aeson (Value (..), object, parseJSON, toJSON, withObject, (.=))
import Data.Aeson.Key qualified as Key
import Data.Aeson.KeyMap qualified as KeyMap
import Data.Aeson.Types (Parser, JSONPathElement (..), (<?>), explicitParseField, parseEither)
import Data.List.NonEmpty (NonEmpty (..))
import Data.List.NonEmpty qualified as NonEmpty
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Text (Text)
import qualified Data.Text as T
import Keiro.Codec.TextSet (encodeTextSet, parseTextSet)
import Keiro.Codec.Structural (bindingFromShape, bindingToShape)
import Keiro.Codec (Codec (..), EventType (..))
import Conformance.StructuralTextSets.Bindings qualified as Bindings
import Conformance.StructuralTextSets.Domain (LabelEnvelope, MaybeTextLabels, TextLabels)
import Generated.StructuralTextSets.Structural.Shape.LabelEnvelope qualified as ShapeLabelEnvelope
import Generated.StructuralTextSets.Structural.Shape.MaybeTextLabels qualified as ShapeMaybeTextLabels
import Generated.StructuralTextSets.Structural.Shape.TextLabels qualified as ShapeTextLabels
encodeLabelEnvelopeMapped :: LabelEnvelope -> Value
encodeLabelEnvelopeMapped = encodeLabelEnvelopeShape . bindingToShape Bindings.labelEnvelopeBinding
parseLabelEnvelopeMapped :: Value -> Parser LabelEnvelope
parseLabelEnvelopeMapped value = bindingFromShape Bindings.labelEnvelopeBinding <$> parseLabelEnvelopeShape value
decodeLabelEnvelopeMapped :: Value -> Either Text LabelEnvelope
decodeLabelEnvelopeMapped = mapLeftText . parseEither parseLabelEnvelopeMapped
encodeLabelEnvelopeShape :: ShapeLabelEnvelope.LabelEnvelopeShape -> Value
encodeLabelEnvelopeShape shape =
object
[ "primary" .= encodeTextSet (shape.primary)
, "optionalLabels" .= maybe Null (\item0 -> encodeTextSet (item0)) (shape.optionalLabels)
, "namedOptional" .= encodeMaybeTextLabelsShape (shape.namedOptional)
, "sequence" .= toJSON (map (\item0 -> encodeTextSet (item0)) (shape.sequence))
, "labelled" .= toJSON (Map.map (\item0 -> encodeTextSet (item0)) (shape.labelled))
]
parseLabelEnvelopeShape :: Value -> Parser ShapeLabelEnvelope.LabelEnvelopeShape
parseLabelEnvelopeShape = withObject "LabelEnvelopeShape" $ \objectValue -> do
rejectUnknownFields "LabelEnvelope" ["primary", "optionalLabels", "namedOptional", "sequence", "labelled"] objectValue
ShapeLabelEnvelope.LabelEnvelope
<$> explicitParseField (parseTextSet) objectValue "primary"
<*> parseOptionalField (pure Nothing) (\value0 -> case value0 of Null -> pure Nothing; other0 -> Just <$> (parseTextSet) other0) objectValue "optionalLabels"
<*> explicitParseField (parseMaybeTextLabelsShape) objectValue "namedOptional"
<*> explicitParseField (\value0 -> do items0 <- (parseJSON value0 :: Parser [Value]); traverse (\(index0, item0) -> (parseTextSet) item0 <?> Index index0) (zip [0..] items0)) objectValue "sequence"
<*> explicitParseField (\value0 -> do items0 <- (parseJSON value0 :: Parser (Map Text Value)); Map.traverseWithKey (\key0 item0 -> (parseTextSet) item0 <?> Key (Key.fromText key0)) items0) objectValue "labelled"
encodeMaybeTextLabelsMapped :: MaybeTextLabels -> Value
encodeMaybeTextLabelsMapped = encodeMaybeTextLabelsShape . bindingToShape Bindings.maybeTextLabelsBinding
parseMaybeTextLabelsMapped :: Value -> Parser MaybeTextLabels
parseMaybeTextLabelsMapped value = bindingFromShape Bindings.maybeTextLabelsBinding <$> parseMaybeTextLabelsShape value
decodeMaybeTextLabelsMapped :: Value -> Either Text MaybeTextLabels
decodeMaybeTextLabelsMapped = mapLeftText . parseEither parseMaybeTextLabelsMapped
encodeMaybeTextLabelsShape :: ShapeMaybeTextLabels.MaybeTextLabelsShape -> Value
encodeMaybeTextLabelsShape value = maybe Null (\item0 -> encodeTextSet (item0)) (value)
parseMaybeTextLabelsShape :: Value -> Parser ShapeMaybeTextLabels.MaybeTextLabelsShape
parseMaybeTextLabelsShape = \value0 -> case value0 of Null -> pure Nothing; other0 -> Just <$> (parseTextSet) other0
encodeTextLabelsMapped :: TextLabels -> Value
encodeTextLabelsMapped = encodeTextLabelsShape . bindingToShape Bindings.textLabelsBinding
parseTextLabelsMapped :: Value -> Parser TextLabels
parseTextLabelsMapped value = bindingFromShape Bindings.textLabelsBinding <$> parseTextLabelsShape value
decodeTextLabelsMapped :: Value -> Either Text TextLabels
decodeTextLabelsMapped = mapLeftText . parseEither parseTextLabelsMapped
encodeTextLabelsShape :: ShapeTextLabels.TextLabelsShape -> Value
encodeTextLabelsShape value = encodeTextSet (value)
parseTextLabelsShape :: Value -> Parser ShapeTextLabels.TextLabelsShape
parseTextLabelsShape = parseTextSet
labelStoreEventTypes :: NonEmpty EventType
labelStoreEventTypes = EventType "LabelsStored" :| [EventType "LabelsAudited", EventType "LegacyLabelsImported"]
labelStoreCodec :: Codec LabelStoreEvent
labelStoreCodec =
Codec
{ eventTypes = labelStoreEventTypes
, eventType = \case
LabelsStored{} -> EventType "LabelsStored"
LabelsAudited{} -> EventType "LabelsAudited"
LegacyLabelsImported{} -> EventType "LegacyLabelsImported"
, schemaVersion = 1
, encode = encodeLabelStoreEvent
, decode = parseLabelStoreEvent
, upcasters = []
}
encodeLabelStoreEvent :: LabelStoreEvent -> Value
encodeLabelStoreEvent = \case
LabelsStored payload ->
object
[ "kind" .= ("LabelsStored" :: Text)
, "labels" .= encodeTextLabelsMapped payload.labels
, "optionalLabels" .= encodeMaybeTextLabelsMapped payload.optionalLabels
, "envelope" .= encodeLabelEnvelopeMapped payload.envelope
]
LabelsAudited payload ->
object
[ "kind" .= ("LabelsAudited" :: Text)
, "labels" .= encodeTextLabelsMapped payload.labels
, "optionalLabels" .= encodeMaybeTextLabelsMapped payload.optionalLabels
, "envelope" .= encodeLabelEnvelopeMapped payload.envelope
]
LegacyLabelsImported payload ->
object
[ "kind" .= ("LegacyLabelsImported" :: Text)
, "labels" .= encodeTextLabelsMapped payload.labels
, "optionalLabels" .= encodeMaybeTextLabelsMapped payload.optionalLabels
, "envelope" .= encodeLabelEnvelopeMapped payload.envelope
]
parseLabelStoreEvent :: EventType -> Value -> Either Text LabelStoreEvent
parseLabelStoreEvent (EventType tag) = mapLeftText . parseEither (withObject "LabelStoreEvent" go)
where
go o = do
case tag of
"LabelsStored" ->
LabelsStored
<$> ( LabelsStoredData
<$> explicitParseField parseTextLabelsMapped o "labels"
<*> parseOptionalField (parseMaybeTextLabelsMapped Null) parseMaybeTextLabelsMapped o "optionalLabels"
<*> explicitParseField parseLabelEnvelopeMapped o "envelope"
)
"LabelsAudited" ->
LabelsAudited
<$> ( LabelsAuditedData
<$> explicitParseField parseTextLabelsMapped o "labels"
<*> parseOptionalField (parseMaybeTextLabelsMapped Null) parseMaybeTextLabelsMapped o "optionalLabels"
<*> explicitParseField parseLabelEnvelopeMapped o "envelope"
)
"LegacyLabelsImported" ->
LegacyLabelsImported
<$> ( LegacyLabelsImportedData
<$> explicitParseField parseTextLabelsMapped o "labels"
<*> parseOptionalField (parseMaybeTextLabelsMapped Null) parseMaybeTextLabelsMapped o "optionalLabels"
<*> explicitParseField parseLabelEnvelopeMapped o "envelope"
)
_ -> fail ("unknown event type " <> show tag <> "; expected one of: " <> renderExpectedEventTypes labelStoreEventTypes)
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
parseOptionalField :: Parser fieldValue -> (Value -> Parser fieldValue) -> KeyMap.KeyMap Value -> Key.Key -> Parser fieldValue
parseOptionalField onMissing parseItem objectValue key =
case KeyMap.lookup key objectValue of
Nothing -> onMissing
Just _ -> explicitParseField parseItem objectValue key
rejectUnknownFields :: String -> [Text] -> KeyMap.KeyMap Value -> Parser ()
rejectUnknownFields label allowed objectValue =
unless (null extras) (fail (label <> " contains unknown fields: " <> show extras))
where
extras = filter (`notElem` allowed) (map Key.toText (KeyMap.keys objectValue))