packages feed

dependent-sum-aeson-orphans-0.1.0.0: src/Data/Dependent/Sum/Orphans.hs

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Data.Dependent.Sum.Orphans where

import Data.Aeson
import Data.Constraint
import Data.Constraint.Forall
import Data.Constraint.Extras
import Data.Dependent.Map (DMap, GCompare)
import qualified Data.Dependent.Map as DMap
import Data.Dependent.Sum
import Data.Some (Some)
import qualified Data.Some as Some

instance (ForallF ToJSON f, Has ToJSON f, ToJSON1 g) => ToJSON (DSum f g) where
  toJSON ((f :: f a) :=> (x :: g a))
    | Dict :: Dict (ToJSON a) <- argDict f
    = toJSON (toJSON f \\ (instF :: ForallF ToJSON f :- ToJSON (f a)), toJSON1 x)

instance (ForallF ToJSON f, Has ToJSON f, ToJSON1 g) => ToJSON (DMap f g) where
    toJSON = toJSON . DMap.toList

instance (FromJSON (Some f), GCompare f, Has FromJSON f, FromJSON1 g) => FromJSON (DSum f g) where
  parseJSON x = do
    (tag, val) <- parseJSON x
    Some.This (parsedTag :: f a) <- parseJSON tag
    val' <- case argDict parsedTag of
      (Dict :: Dict (FromJSON a)) -> parseJSON1 val
    return $ parsedTag :=> val'

instance (FromJSON (Some f), GCompare f, Has FromJSON f, FromJSON1 g) => FromJSON (DMap f g) where
    parseJSON = fmap DMap.fromList . parseJSON