{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module ByOtherNamesH.Aeson
(
JSONRubric (..),
JSONRecord (..),
FromToJSON (..),
fromToJSON,
GeneralJSONRecord (..),
Aliased (aliases),
aliasListBegin,
alias,
aliasListEnd,
SlotList,
singleSlot,
slot,
slotListEnd,
FromJSON,
ToJSON,
)
where
import ByOtherNamesH
import Data.Aeson
import Data.Aeson.Key (fromText, toText)
import Data.Aeson.Types
import Data.Functor.Compose
import Data.Kind
import Data.Proxy
import Data.Void
import GHC.Generics
import GHC.TypeLits
import Data.Functor.Identity
import Data.Functor.Const
data JSONRubric = JSON
instance Rubric JSON where
type AliasType JSON = Key
type WrapperType JSON = FromToJSON
data FromToJSON v = FromToJSON {
forall v. FromToJSON v -> Value -> Parser v
parseJSON' :: Value -> Parser v,
forall v. FromToJSON v -> v -> Value
toJSON' :: v -> Value
}
fromToJSON :: (ToJSON v, FromJSON v) => FromToJSON v
fromToJSON :: forall v. (ToJSON v, FromJSON v) => FromToJSON v
fromToJSON = FromToJSON { parseJSON' :: Value -> Parser v
parseJSON' = forall a. FromJSON a => Value -> Parser a
parseJSON, toJSON' :: v -> Value
toJSON' = forall a. ToJSON a => a -> Value
toJSON}
type JSONRecord :: Symbol -> Type -> Type
newtype JSONRecord objectName r = JSONRecord r
deriving via (GeneralJSONRecord 'JSON objectName r) instance (KnownSymbol objectName, Aliased 'JSON r, GRecord (Rep r)) => FromJSON (JSONRecord objectName r)
deriving via (GeneralJSONRecord 'JSON objectName r) instance (Aliased 'JSON r, GRecord (Rep r)) => ToJSON (JSONRecord objectName r)
type GeneralJSONRecord :: rubric -> Symbol -> Type -> Type
newtype GeneralJSONRecord rubric objectName r = GeneralJSONRecord r
instance (KnownSymbol objectName,
Rubric rubric,
Aliased rubric r,
AliasType rubric ~ Key,
WrapperType rubric ~ FromToJSON,
GRecord (Rep r))
=> FromJSON (GeneralJSONRecord rubric objectName r) where
parseJSON :: Value -> Parser (GeneralJSONRecord rubric objectName r)
parseJSON Value
v =
let FieldParser Object -> Parser (Rep r Any)
parser =
forall (rep :: * -> *) (g :: * -> *) a (h :: * -> *) z.
(GRecord rep, Applicative g) =>
Aliases rep a h -> (forall v. a -> h v -> g v) -> g (rep z)
gToRecord
(forall k (k :: k) r.
Aliased k r =>
Aliases (Rep r) (AliasType k) (WrapperType k)
aliases @_ @rubric @r)
(\Key
fieldName (FromToJSON {Value -> Parser v
parseJSON' :: Value -> Parser v
parseJSON' :: forall v. FromToJSON v -> Value -> Parser v
parseJSON'}) -> forall a. (Object -> Parser a) -> FieldParser a
FieldParser (\Object
o -> forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField Value -> Parser v
parseJSON' Object
o Key
fieldName))
objectName :: String
objectName = forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
Proxy @objectName)
in forall rubric (rubric :: rubric) (objectName :: Symbol) r.
r -> GeneralJSONRecord rubric objectName r
GeneralJSONRecord forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a x. Generic a => Rep a x -> a
to forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
objectName Object -> Parser (Rep r Any)
parser Value
v
newtype FieldParser a = FieldParser (Object -> Parser a)
deriving (forall a b. a -> FieldParser b -> FieldParser a
forall a b. (a -> b) -> FieldParser a -> FieldParser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> FieldParser b -> FieldParser a
$c<$ :: forall a b. a -> FieldParser b -> FieldParser a
fmap :: forall a b. (a -> b) -> FieldParser a -> FieldParser b
$cfmap :: forall a b. (a -> b) -> FieldParser a -> FieldParser b
Functor, Functor FieldParser
forall a. a -> FieldParser a
forall a b. FieldParser a -> FieldParser b -> FieldParser a
forall a b. FieldParser a -> FieldParser b -> FieldParser b
forall a b. FieldParser (a -> b) -> FieldParser a -> FieldParser b
forall a b c.
(a -> b -> c) -> FieldParser a -> FieldParser b -> FieldParser c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. FieldParser a -> FieldParser b -> FieldParser a
$c<* :: forall a b. FieldParser a -> FieldParser b -> FieldParser a
*> :: forall a b. FieldParser a -> FieldParser b -> FieldParser b
$c*> :: forall a b. FieldParser a -> FieldParser b -> FieldParser b
liftA2 :: forall a b c.
(a -> b -> c) -> FieldParser a -> FieldParser b -> FieldParser c
$cliftA2 :: forall a b c.
(a -> b -> c) -> FieldParser a -> FieldParser b -> FieldParser c
<*> :: forall a b. FieldParser (a -> b) -> FieldParser a -> FieldParser b
$c<*> :: forall a b. FieldParser (a -> b) -> FieldParser a -> FieldParser b
pure :: forall a. a -> FieldParser a
$cpure :: forall a. a -> FieldParser a
Applicative) via ((->) Object `Compose` Parser)
instance (Rubric rubric,
Aliased rubric r,
AliasType rubric ~ Key,
WrapperType rubric ~ FromToJSON,
GRecord (Rep r)) => ToJSON (GeneralJSONRecord rubric objectName r) where
toJSON :: GeneralJSONRecord rubric objectName r -> Value
toJSON (GeneralJSONRecord r
o) = do
let plainRecord :: Aliases (Rep r) String Identity
plainRecord = forall (rep :: * -> *) z.
GRecord rep =>
rep z -> Aliases rep String Identity
gFromRecord forall a b. (a -> b) -> a -> b
$ forall a x. Generic a => a -> Rep a x
from @r r
o
deserializers :: Aliases (Rep r) (AliasType rubric) (WrapperType rubric)
deserializers = forall k (k :: k) r.
Aliased k r =>
Aliases (Rep r) (AliasType k) (WrapperType k)
aliases @_ @rubric @r
combineAliases :: p -> p -> p
combineAliases p
_ p
k = p
k
combineWrappers :: Identity v -> FromToJSON v -> Const Value b
combineWrappers (Identity v
v) (FromToJSON {v -> Value
toJSON' :: v -> Value
toJSON' :: forall v. FromToJSON v -> v -> Value
toJSON'}) = forall {k} a (b :: k). a -> Const a b
Const (v -> Value
toJSON' v
v)
eachFieldRendered :: Aliases (Rep r) Key (Const Value)
eachFieldRendered = forall (rep :: * -> *) a1 a2 ar (h1 :: * -> *) (h2 :: * -> *)
(hr :: * -> *).
GRecord rep =>
(a1 -> a2 -> ar)
-> (forall v. h1 v -> h2 v -> hr v)
-> Aliases rep a1 h1
-> Aliases rep a2 h2
-> Aliases rep ar hr
gBiliftA2RecordAliases forall {p} {p}. p -> p -> p
combineAliases forall {k} {v} {b :: k}.
Identity v -> FromToJSON v -> Const Value b
combineWrappers Aliases (Rep r) String Identity
plainRecord Aliases (Rep r) (AliasType rubric) (WrapperType rubric)
deserializers
Const [Pair]
objects = forall (rep :: * -> *) (g :: * -> *) a (h :: * -> *) z.
(GRecord rep, Applicative g) =>
Aliases rep a h -> (forall v. a -> h v -> g v) -> g (rep z)
gToRecord Aliases (Rep r) Key (Const Value)
eachFieldRendered (\Key
a (Const Value
v) -> forall {k} a (b :: k). a -> Const a b
Const [(Key
a,Value
v)])
[Pair] -> Value
object [Pair]
objects