{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Development.Guardian.Graph.Adapter.Types (
  PackageBuildParser (..),
  CustomPackageOptions,
  PackageGraphOptions (..),
  ComponentsOptions (..),
  StandardAdapters (..),
) where

import Data.Aeson (FromJSON (..))
import qualified Data.Aeson as J
import GHC.Generics (Generic)
import Path (Abs, Dir, Path)

data StandardAdapters = Stack | Cabal
  deriving (Int -> StandardAdapters -> ShowS
[StandardAdapters] -> ShowS
StandardAdapters -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StandardAdapters] -> ShowS
$cshowList :: [StandardAdapters] -> ShowS
show :: StandardAdapters -> String
$cshow :: StandardAdapters -> String
showsPrec :: Int -> StandardAdapters -> ShowS
$cshowsPrec :: Int -> StandardAdapters -> ShowS
Show, StandardAdapters -> StandardAdapters -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StandardAdapters -> StandardAdapters -> Bool
$c/= :: StandardAdapters -> StandardAdapters -> Bool
== :: StandardAdapters -> StandardAdapters -> Bool
$c== :: StandardAdapters -> StandardAdapters -> Bool
Eq, Eq StandardAdapters
StandardAdapters -> StandardAdapters -> Bool
StandardAdapters -> StandardAdapters -> Ordering
StandardAdapters -> StandardAdapters -> StandardAdapters
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: StandardAdapters -> StandardAdapters -> StandardAdapters
$cmin :: StandardAdapters -> StandardAdapters -> StandardAdapters
max :: StandardAdapters -> StandardAdapters -> StandardAdapters
$cmax :: StandardAdapters -> StandardAdapters -> StandardAdapters
>= :: StandardAdapters -> StandardAdapters -> Bool
$c>= :: StandardAdapters -> StandardAdapters -> Bool
> :: StandardAdapters -> StandardAdapters -> Bool
$c> :: StandardAdapters -> StandardAdapters -> Bool
<= :: StandardAdapters -> StandardAdapters -> Bool
$c<= :: StandardAdapters -> StandardAdapters -> Bool
< :: StandardAdapters -> StandardAdapters -> Bool
$c< :: StandardAdapters -> StandardAdapters -> Bool
compare :: StandardAdapters -> StandardAdapters -> Ordering
$ccompare :: StandardAdapters -> StandardAdapters -> Ordering
Ord)

data family CustomPackageOptions backend

newtype PackageBuildParser backend = PackageBuildParser
  { forall backend.
PackageBuildParser backend
-> Path Abs Dir -> PackageGraphOptions backend
withTargetPath ::
      Path Abs Dir ->
      PackageGraphOptions backend
  }

instance
  FromJSON (CustomPackageOptions backend) =>
  FromJSON (PackageBuildParser backend)
  where
  parseJSON :: Value -> Parser (PackageBuildParser backend)
parseJSON Value
obj = do
    CustomPackageOptions backend
customOptions <- forall a. FromJSON a => Value -> Parser a
parseJSON Value
obj
    ComponentsOptions
components <- forall a. FromJSON a => Value -> Parser a
parseJSON Value
obj
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall backend.
(Path Abs Dir -> PackageGraphOptions backend)
-> PackageBuildParser backend
PackageBuildParser forall a b. (a -> b) -> a -> b
$ \Path Abs Dir
targetPath -> PackageGraphOptions {Path Abs Dir
ComponentsOptions
CustomPackageOptions backend
customOptions :: CustomPackageOptions backend
components :: ComponentsOptions
targetPath :: Path Abs Dir
targetPath :: Path Abs Dir
components :: ComponentsOptions
customOptions :: CustomPackageOptions backend
..}

data PackageGraphOptions backend = PackageGraphOptions
  { forall backend. PackageGraphOptions backend -> Path Abs Dir
targetPath :: !(Path Abs Dir)
  , forall backend. PackageGraphOptions backend -> ComponentsOptions
components :: !ComponentsOptions
  , forall backend.
PackageGraphOptions backend -> CustomPackageOptions backend
customOptions :: CustomPackageOptions backend
  }
  deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall backend x.
Rep (PackageGraphOptions backend) x -> PackageGraphOptions backend
forall backend x.
PackageGraphOptions backend -> Rep (PackageGraphOptions backend) x
$cto :: forall backend x.
Rep (PackageGraphOptions backend) x -> PackageGraphOptions backend
$cfrom :: forall backend x.
PackageGraphOptions backend -> Rep (PackageGraphOptions backend) x
Generic)

deriving instance
  Show (CustomPackageOptions backend) =>
  Show (PackageGraphOptions backend)

deriving instance
  Eq (CustomPackageOptions backend) =>
  Eq (PackageGraphOptions backend)

deriving instance
  Ord (CustomPackageOptions backend) =>
  Ord (PackageGraphOptions backend)

data ComponentsOptions = ComponentsOptions
  { ComponentsOptions -> Bool
tests :: Bool
  , ComponentsOptions -> Bool
benchmarks :: Bool
  }
  deriving (Int -> ComponentsOptions -> ShowS
[ComponentsOptions] -> ShowS
ComponentsOptions -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ComponentsOptions] -> ShowS
$cshowList :: [ComponentsOptions] -> ShowS
show :: ComponentsOptions -> String
$cshow :: ComponentsOptions -> String
showsPrec :: Int -> ComponentsOptions -> ShowS
$cshowsPrec :: Int -> ComponentsOptions -> ShowS
Show, ComponentsOptions -> ComponentsOptions -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ComponentsOptions -> ComponentsOptions -> Bool
$c/= :: ComponentsOptions -> ComponentsOptions -> Bool
== :: ComponentsOptions -> ComponentsOptions -> Bool
$c== :: ComponentsOptions -> ComponentsOptions -> Bool
Eq, Eq ComponentsOptions
ComponentsOptions -> ComponentsOptions -> Bool
ComponentsOptions -> ComponentsOptions -> Ordering
ComponentsOptions -> ComponentsOptions -> ComponentsOptions
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ComponentsOptions -> ComponentsOptions -> ComponentsOptions
$cmin :: ComponentsOptions -> ComponentsOptions -> ComponentsOptions
max :: ComponentsOptions -> ComponentsOptions -> ComponentsOptions
$cmax :: ComponentsOptions -> ComponentsOptions -> ComponentsOptions
>= :: ComponentsOptions -> ComponentsOptions -> Bool
$c>= :: ComponentsOptions -> ComponentsOptions -> Bool
> :: ComponentsOptions -> ComponentsOptions -> Bool
$c> :: ComponentsOptions -> ComponentsOptions -> Bool
<= :: ComponentsOptions -> ComponentsOptions -> Bool
$c<= :: ComponentsOptions -> ComponentsOptions -> Bool
< :: ComponentsOptions -> ComponentsOptions -> Bool
$c< :: ComponentsOptions -> ComponentsOptions -> Bool
compare :: ComponentsOptions -> ComponentsOptions -> Ordering
$ccompare :: ComponentsOptions -> ComponentsOptions -> Ordering
Ord, forall x. Rep ComponentsOptions x -> ComponentsOptions
forall x. ComponentsOptions -> Rep ComponentsOptions x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ComponentsOptions x -> ComponentsOptions
$cfrom :: forall x. ComponentsOptions -> Rep ComponentsOptions x
Generic)

instance FromJSON ComponentsOptions where
  parseJSON :: Value -> Parser ComponentsOptions
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
J.withObject String
"{components: ...}" forall a b. (a -> b) -> a -> b
$ \Object
dic -> do
    Maybe Object
mcomp <- Object
dic forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
J..:? Key
"components"
    case Maybe Object
mcomp of
      Maybe Object
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ComponentsOptions {tests :: Bool
tests = Bool
True, benchmarks :: Bool
benchmarks = Bool
True}
      Just Object
comps -> do
        Bool
tests <- Object
comps forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"tests" forall a. Parser (Maybe a) -> a -> Parser a
J..!= Bool
True
        Bool
benchmarks <- Object
comps forall a. FromJSON a => Object -> Key -> Parser a
J..: Key
"benchmarks" forall a. Parser (Maybe a) -> a -> Parser a
J..!= Bool
True
        forall (f :: * -> *) a. Applicative f => a -> f a
pure ComponentsOptions {Bool
benchmarks :: Bool
tests :: Bool
benchmarks :: Bool
tests :: Bool
..}