versioning-0.3.0.0: src/Versioning/JSON.hs
-- | JSON-specific deserialization utilities.
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE UndecidableInstances #-}
module Versioning.JSON
( -- * Types
Applied
, JsonDecodableTo
, JsonDecodableToFrom
-- * Decoding and upgrading
, fromJsonAnyVersion
, fromJsonAnyVersionStrict
, fromJsonAnyVersionEither
, fromJsonAnyVersionEitherStrict
, fromJsonAnyVersionFrom
-- * Decoding and appyling an action
, withJsonAnyVersion
, withJsonAnyVersionStrict
, withJsonAnyVersionEither
, withJsonAnyVersionEitherStrict
, withJsonAnyVersionFrom
, withJsonAnyVersionM
, withJsonAnyVersionStrictM
, withJsonAnyVersionEitherM
, withJsonAnyVersionEitherStrictM
, withJsonAnyVersionFromM
)
where
import Data.Aeson (FromJSON, decode, decodeStrict,
eitherDecode, eitherDecodeStrict)
import qualified Data.ByteString as StrictBS
import qualified Data.ByteString.Lazy as LazyBS
import Versioning.Base
import Versioning.Internal.Decoding
-- | Decode a JSON string by trying all the versions decrementally
-- and upgrade the decoded object to the newest version.
fromJsonAnyVersion
:: forall v a . JsonDecodableTo v a => LazyBS.ByteString -> Maybe (a v)
fromJsonAnyVersion = decodeAnyVersion jsonDecode
-- | Like 'fromJsonAnyVersion' but it reads from a strict 'ByteString'
fromJsonAnyVersionStrict
:: forall v a . JsonDecodableTo v a => StrictBS.ByteString -> Maybe (a v)
fromJsonAnyVersionStrict = decodeAnyVersion jsonDecodeStrict
-- | Like 'fromJsonAnyVersion' but returns a message when decoding fails
fromJsonAnyVersionEither
:: forall v a
. JsonDecodableTo v a
=> LazyBS.ByteString
-> Either String (a v)
fromJsonAnyVersionEither = decodeAnyVersion jsonEitherDecode
-- | Like 'fromJsonAnyVersionStrict' but returns a message when decoding fails
fromJsonAnyVersionEitherStrict
:: forall v a
. JsonDecodableTo v a
=> StrictBS.ByteString
-> Either String (a v)
fromJsonAnyVersionEitherStrict = decodeAnyVersion jsonEitherDecodeStrict
-- | Like 'fromJsonAnyVersion', with an additional type-parameter
-- indicating the oldest version you want to be able to decode
fromJsonAnyVersionFrom
:: forall from v a
. JsonDecodableToFrom from v a
=> LazyBS.ByteString
-> Maybe (a v)
fromJsonAnyVersionFrom = decodeAnyVersionFrom @from jsonDecode
-- | Decode a JSON string by trying all the versions decrementally
-- and apply an action to the decoded object at its original version.
withJsonAnyVersionM
:: forall c a v m
. (WithAnyVersion v a c FromJSON, Applicative m, c (a v))
=> ApplyM m a c
-> LazyBS.ByteString
-> m (Maybe (Applied c a))
withJsonAnyVersionM = withAnyVersionM @v @c @a jsonDecode
-- | Like 'withJsonAnyVersionM' but it reads from a strict 'ByteString'
withJsonAnyVersionStrictM
:: forall c a v m
. (WithAnyVersion v a c FromJSON, Applicative m, c (a v))
=> ApplyM m a c
-> StrictBS.ByteString
-> m (Maybe (Applied c a))
withJsonAnyVersionStrictM = withAnyVersionM @v @c @a jsonDecodeStrict
-- | Like 'withJsonAnyVersionM' but returns a message when decoding fails
withJsonAnyVersionEitherM
:: forall c a v m
. (WithAnyVersion v a c FromJSON, Applicative m, c (a v))
=> ApplyM m a c
-> LazyBS.ByteString
-> m (Either String (Applied c a))
withJsonAnyVersionEitherM = withAnyVersionM @v @c @a jsonEitherDecode
-- | Like 'withJsonAnyVersionStrictM' but returns a message when decoding fails
withJsonAnyVersionEitherStrictM
:: forall c a v m
. (WithAnyVersion v a c FromJSON, Applicative m, c (a v))
=> ApplyM m a c
-> StrictBS.ByteString
-> m (Either String (Applied c a))
withJsonAnyVersionEitherStrictM =
withAnyVersionM @v @c @a jsonEitherDecodeStrict
-- | Like 'withJsonAnyVersionM', with an additional type-parameter
-- indicating the oldest version you want to be able to decode
withJsonAnyVersionFromM
:: forall from c a v m
. (WithAnyVersionFrom from v a c FromJSON, Applicative m, c (a v))
=> ApplyM m a c
-> LazyBS.ByteString
-> m (Maybe (Applied c a))
withJsonAnyVersionFromM = withAnyVersionFromM @from @v @c @a jsonDecode
-- | Decode a JSON string by trying all the versions decrementally
-- and apply a pure function to the decoded object at its original version.
withJsonAnyVersion
:: forall c a v
. (WithAnyVersion v a c FromJSON, c (a v))
=> Apply a c
-> LazyBS.ByteString
-> Maybe (Applied c a)
withJsonAnyVersion = withAnyVersion @v @c @a jsonDecode
-- | Like 'withJsonAnyVersion' but it reads from a strict 'ByteString'
withJsonAnyVersionStrict
:: forall c a v
. (WithAnyVersion v a c FromJSON, c (a v))
=> Apply a c
-> StrictBS.ByteString
-> Maybe (Applied c a)
withJsonAnyVersionStrict = withAnyVersion @v @c @a jsonDecodeStrict
-- | Like 'withJsonAnyVersion' but returns a message when decoding fails
withJsonAnyVersionEither
:: forall c a v
. (WithAnyVersion v a c FromJSON, c (a v))
=> Apply a c
-> LazyBS.ByteString
-> Either String (Applied c a)
withJsonAnyVersionEither = withAnyVersion @v @c @a jsonEitherDecode
-- | Like 'withJsonAnyVersionStrict' but returns a message when decoding fails
withJsonAnyVersionEitherStrict
:: forall c a v
. (WithAnyVersion v a c FromJSON, c (a v))
=> Apply a c
-> StrictBS.ByteString
-> Either String (Applied c a)
withJsonAnyVersionEitherStrict = withAnyVersion @v @c @a jsonEitherDecodeStrict
-- | Like 'withJsonAnyVersion', with an additional type-parameter
-- indicating the oldest version you want to be able to decode
withJsonAnyVersionFrom
:: forall from c a v
. (WithAnyVersionFrom from v a c FromJSON, c (a v))
=> Apply a c
-> LazyBS.ByteString
-> Maybe (Applied c a)
withJsonAnyVersionFrom = withAnyVersionFrom @from @v @c @a jsonDecode
-- | Decode with the aeson 'decode' function
jsonDecode :: Decoder FromJSON LazyBS.ByteString Maybe a
jsonDecode = Decoder decode
-- | Decode with the aeson 'decodeStrict' function
jsonDecodeStrict :: Decoder FromJSON StrictBS.ByteString Maybe a
jsonDecodeStrict = Decoder decodeStrict
-- | Decode with the aeson 'eitherDecode' function
jsonEitherDecode :: Decoder FromJSON LazyBS.ByteString (Either String) a
jsonEitherDecode = Decoder eitherDecode
-- | Decode with the aeson 'eitherDecodeStrict' function
jsonEitherDecodeStrict :: Decoder FromJSON StrictBS.ByteString (Either String) a
jsonEitherDecodeStrict = Decoder eitherDecodeStrict
-- | Handy constraint synonym to be used with 'fromJsonAnyVersion'
type JsonDecodableTo v a = JsonDecodableToFrom V0 v a
-- | Like 'JsonDecodableTo', with an additional type-parameter
-- indicating the oldest version you want to be able to decode
type JsonDecodableToFrom from v a = DecodableToFrom from FromJSON v a