{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Some orphan @To/FromJSON@ instances for terms and values.  We have
-- to put them all here to avoid circular module dependencies.
module Swarm.Language.JSON where

import Data.Aeson (FromJSON (..), ToJSON (..), genericParseJSON, genericToJSON, withText)
import Data.Aeson qualified as Ae
import Swarm.Language.Pipeline (processTermEither)
import Swarm.Language.Pretty (prettyText)
import Swarm.Language.Syntax (Term)
import Swarm.Language.Syntax.Pattern (Syntax, TSyntax)
import Swarm.Language.Value (Env, Value)
import Swarm.Util.JSON (optionsMinimize)
import Witch (into)

instance FromJSON TSyntax where
  parseJSON :: Value -> Parser TSyntax
parseJSON = String -> (Text -> Parser TSyntax) -> Value -> Parser TSyntax
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Term" ((Text -> Parser TSyntax) -> Value -> Parser TSyntax)
-> (Text -> Parser TSyntax) -> Value -> Parser TSyntax
forall a b. (a -> b) -> a -> b
$ (Text -> Parser TSyntax)
-> (TSyntax -> Parser TSyntax)
-> Either Text TSyntax
-> Parser TSyntax
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Parser TSyntax
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser TSyntax)
-> (Text -> String) -> Text -> Parser TSyntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall target source. From source target => source -> target
into @String) TSyntax -> Parser TSyntax
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text TSyntax -> Parser TSyntax)
-> (Text -> Either Text TSyntax) -> Text -> Parser TSyntax
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text TSyntax
processTermEither

instance ToJSON TSyntax where
  toJSON :: TSyntax -> Value
toJSON = Text -> Value
Ae.String (Text -> Value) -> (TSyntax -> Text) -> TSyntax -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TSyntax -> Text
forall a. PrettyPrec a => a -> Text
prettyText

instance FromJSON Term
instance FromJSON Syntax
instance ToJSON Term
instance ToJSON Syntax

instance ToJSON Value where
  toJSON :: Value -> Value
toJSON = Options -> Value -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
optionsMinimize

instance FromJSON Value where
  parseJSON :: Value -> Parser Value
parseJSON = Options -> Value -> Parser Value
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
optionsMinimize

deriving instance FromJSON Env
deriving instance ToJSON Env