registry-aeson-0.3.0.0: test/Test/Data/Registry/Aeson/Examples/Protocols.hs
{-# LANGUAGE PartialTypeSignatures #-}
{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
module Test.Data.Registry.Aeson.Examples.Protocols where
import Data.Aeson hiding (encode)
import Data.Registry
import Data.Registry.Aeson.Decoder
import Protolude hiding (Product)
import Test.Data.Registry.Aeson.Examples.Deliverix
-- | This protocol is defined for the current data model
currentProtocol :: Registry _ _
currentProtocol =
$(makeDecoder ''Delivery)
<: $(makeDecoder ''Order)
<: decodeMapOf @Int @Product
<: decodeMaybeOf @Coupon
<: $(makeDecoder ''Coupon)
<: $(makeDecoder ''Product)
<: $(makeDecoder ''Customer)
<: $(makeDecoder ''Address)
<: $(makeDecoder ''StreetNumber)
<: $(makeDecoder ''Price)
<: jsonDecoder @Text
<: decodeKey @Int parseInt
<: decodeMaybeOf @Double
<: jsonDecoder @Double
<: val (defaultOptions {unwrapUnaryRecords = True}) -- to unwrap StreetNumber
<: defaultDecoderOptions
-- | The first version of the protocol did not have coupons
-- And street numbers were implemented as an Int (but street numbers can also have letters)
-- In this registry we specify how existing decoders need to be modified / extended in order to be
-- able to still read old values
protocolV1 :: Registry _ _
protocolV1 =
val (defaultOptions {omitNothingFields = True}) -- to allow for missing coupons
<: fun streetNumberDecoder
<: jsonDecoder @Int
<: currentProtocol
-- | A street number used to be a single Int
streetNumberDecoder :: Decoder Int -> Decoder StreetNumber
streetNumberDecoder = fmap (StreetNumber . show)
-- | Read map keys that are Ints
parseInt :: Text -> Either Text Int
parseInt t = maybe (Left $ "the key " <> t <> " is not an Int") Right (readMaybe t)