Last active
August 20, 2017 07:19
-
-
Save lotz84/5a5fd1aba842bbf111a7f5c548f40cfa to your computer and use it in GitHub Desktop.
FromJSON, ToJSON instances for Bookkeeper's extensible record.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
module Bookkeeper.FromJSON where | |
import Bookkeeper.Internal (Book'(..)) | |
import Data.Aeson (FromJSON(..), Object, withObject, (.:)) | |
import Data.Aeson.Types (Parser(..)) | |
import qualified Data.Text as Text | |
import Data.Type.Map (Map(..), Mapping(..), Var(..)) | |
import GHC.TypeLits (Symbol, KnownSymbol, symbolVal) | |
import Data.Kind (Type) | |
import Data.Proxy (Proxy(..)) | |
instance Obj2Map m => FromJSON (Book' m) where | |
parseJSON = withObject "Object" (fmap Book . obj2Map @m) | |
class Obj2Map (m :: [Mapping Symbol Type]) where | |
obj2Map :: Object -> Parser (Map m) | |
instance Obj2Map '[] where | |
obj2Map obj = pure Empty | |
instance (KnownSymbol k, FromJSON v, Obj2Map m) => Obj2Map ((k :-> v) ': m) where | |
obj2Map obj = do | |
v <- obj .: Text.pack (symbolVal (Proxy @k)) | |
rest <- obj2Map @m obj | |
pure $ Ext (Var @k) v rest |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE TypeFamilies #-} | |
module Bookkeeper.ToJSON where | |
import Bookkeeper.Internal (Book'(..)) | |
import Data.Aeson (ToJSON(..), object, (.=)) | |
import Data.Aeson.Types (Pair) | |
import qualified Data.Text as Text | |
import Data.Type.Map (Map(..), Mapping(..)) | |
import GHC.TypeLits (KnownSymbol, Symbol) | |
import Data.Kind (Type) | |
instance ToPairs m => ToJSON (Book' m) where | |
toJSON (Book m) = object $ toPairs m | |
class ToPairs (m :: [Mapping Symbol Type]) where | |
toPairs :: Map m -> [Pair] | |
instance ToPairs '[] where | |
toPairs _ = [] | |
instance (KnownSymbol k, ToJSON v, ToPairs m) => ToPairs ((k :-> v) ': m) where | |
toPairs (Ext k v m) = (Text.pack (show k) .= toJSON v) : toPairs m |
Author
lotz84
commented
Aug 20, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment