{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.Ninja.IR.Build
(
Build, makeBuild, buildRule, buildOuts, buildDeps
, BuildConstraint
) where
import qualified Control.Lens as Lens
import Data.Aeson ((.:), (.=))
import qualified Data.Aeson as Aeson
import Data.Text (Text)
import Data.HashSet (HashSet)
import qualified Data.HashSet as HS
import Control.DeepSeq (NFData)
import Data.Hashable (Hashable)
import GHC.Generics (Generic)
import qualified Test.SmallCheck.Series as SC
import GHC.Exts (Constraint)
import Language.Ninja.IR.Rule (Rule)
import Language.Ninja.IR.Target (Dependency, Output)
import Flow ((|>))
data Build
= MkBuild
{ _buildRule :: !Rule
, _buildOuts :: !(HashSet Output)
, _buildDeps :: !(HashSet Dependency)
}
deriving (Eq, Show, Generic)
{-# INLINE makeBuild #-}
makeBuild :: Rule -> Build
makeBuild rule = MkBuild
{ _buildRule = rule
, _buildOuts = HS.empty
, _buildDeps = HS.empty
}
{-# INLINE buildRule #-}
buildRule :: Lens.Lens' Build Rule
buildRule = Lens.lens _buildRule
$ \(MkBuild {..}) x -> MkBuild { _buildRule = x, .. }
{-# INLINE buildOuts #-}
buildOuts :: Lens.Lens' Build (HashSet Output)
buildOuts = Lens.lens _buildOuts
$ \(MkBuild {..}) x -> MkBuild { _buildOuts = x, .. }
{-# INLINE buildDeps #-}
buildDeps :: Lens.Lens' Build (HashSet Dependency)
buildDeps = Lens.lens _buildDeps
$ \(MkBuild {..}) x -> MkBuild { _buildDeps = x, .. }
instance Aeson.ToJSON Build where
toJSON (MkBuild {..})
= [ "rule" .= _buildRule
, "outputs" .= _buildOuts
, "dependencies" .= _buildDeps
] |> Aeson.object
instance Aeson.FromJSON Build where
parseJSON = (Aeson.withObject "Build" $ \o -> do
_buildRule <- (o .: "rule") >>= pure
_buildOuts <- (o .: "outputs") >>= pure
_buildDeps <- (o .: "dependencies") >>= pure
pure (MkBuild {..}))
instance Hashable Build
instance NFData Build
instance (Monad m, BuildConstraint (SC.Serial m)) => SC.Serial m Build
instance (Monad m, BuildConstraint (SC.CoSerial m)) => SC.CoSerial m Build
type BuildConstraint (c :: * -> Constraint)
= ( c Text
, c (HashSet Output)
, c (HashSet Dependency)
)