{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Mensam.API.Aeson.StaticText.Internal where

import Mensam.API.Aeson.StaticText.Internal.Union qualified as Union

import Control.Applicative
import Data.Aeson qualified as A
import Data.SOP qualified as SOP
import Text.Read qualified

instance Read (SOP.NS f '[]) where
  readPrec :: ReadPrec (NS f '[])
readPrec = String -> ReadPrec (NS f '[])
forall a. String -> ReadPrec a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot read empty sum"
deriving stock instance (Read (f x), Read (SOP.NS f xs)) => Read (SOP.NS f (x : xs))

instance A.ToJSON (SOP.NS f '[]) where
  toJSON :: NS f '[] -> Value
toJSON = \case {}
instance (A.ToJSON (f x), A.ToJSON (SOP.NS f xs), Union.Unique (x : xs)) => A.ToJSON (SOP.NS f (x : xs)) where
  toJSON :: NS f (x : xs) -> Value
toJSON = \case
    SOP.Z f x
ix -> f x -> Value
forall a. ToJSON a => a -> Value
A.toJSON f x
ix
    SOP.S NS f xs
ns -> NS f xs -> Value
forall a. ToJSON a => a -> Value
A.toJSON NS f xs
ns

instance A.FromJSON (SOP.NS f '[]) where
  parseJSON :: Value -> Parser (NS f '[])
parseJSON Value
_ = String -> Parser (NS f '[])
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot parse empty sum"
instance (A.FromJSON (f x), A.FromJSON (SOP.NS f xs), Union.Unique (x : xs)) => A.FromJSON (SOP.NS f (x : xs)) where
  parseJSON :: Value -> Parser (NS f (x : xs))
parseJSON Value
value = (f x -> NS f (x : xs)
forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
SOP.Z (f x -> NS f (x : xs)) -> Parser (f x) -> Parser (NS f (x : xs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
A.parseJSON @(f x) Value
value) Parser (NS f (x : xs))
-> Parser (NS f (x : xs)) -> Parser (NS f (x : xs))
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (NS f xs -> NS f (x : xs)
forall {k} (a :: k -> *) (xs :: [k]) (x :: k).
NS a xs -> NS a (x : xs)
SOP.S (NS f xs -> NS f (x : xs))
-> Parser (NS f xs) -> Parser (NS f (x : xs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSON a => Value -> Parser a
A.parseJSON @(SOP.NS f xs) Value
value)

deriving newtype instance A.ToJSON a => A.ToJSON (SOP.I a)
deriving newtype instance A.FromJSON a => A.FromJSON (SOP.I a)