{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell       #-}

module Distribution.Nixpkgs.Haskell.BuildInfo
  ( BuildInfo
  , haskell, pkgconfig, system, tool, pPrintBuildInfo
  )
  where

import Control.DeepSeq
import Control.Lens
import Data.Semigroup as Sem
import Data.Set ( Set )
import Data.Set.Lens
import GHC.Generics ( Generic )
import Language.Nix
import Language.Nix.PrettyPrinting hiding ( (<>) )

data BuildInfo = BuildInfo
  { BuildInfo -> Set Binding
_haskell   :: Set Binding
  , BuildInfo -> Set Binding
_pkgconfig :: Set Binding
  , BuildInfo -> Set Binding
_system    :: Set Binding
  , BuildInfo -> Set Binding
_tool      :: Set Binding
  }
  deriving (Int -> BuildInfo -> ShowS
[BuildInfo] -> ShowS
BuildInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BuildInfo] -> ShowS
$cshowList :: [BuildInfo] -> ShowS
show :: BuildInfo -> String
$cshow :: BuildInfo -> String
showsPrec :: Int -> BuildInfo -> ShowS
$cshowsPrec :: Int -> BuildInfo -> ShowS
Show, BuildInfo -> BuildInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BuildInfo -> BuildInfo -> Bool
$c/= :: BuildInfo -> BuildInfo -> Bool
== :: BuildInfo -> BuildInfo -> Bool
$c== :: BuildInfo -> BuildInfo -> Bool
Eq, forall x. Rep BuildInfo x -> BuildInfo
forall x. BuildInfo -> Rep BuildInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BuildInfo x -> BuildInfo
$cfrom :: forall x. BuildInfo -> Rep BuildInfo x
Generic)

makeLenses ''BuildInfo

instance Each BuildInfo BuildInfo (Set Binding) (Set Binding) where
  each :: Traversal BuildInfo BuildInfo (Set Binding) (Set Binding)
each Set Binding -> f (Set Binding)
f (BuildInfo Set Binding
a Set Binding
b Set Binding
c Set Binding
d) = Set Binding
-> Set Binding -> Set Binding -> Set Binding -> BuildInfo
BuildInfo forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Binding -> f (Set Binding)
f Set Binding
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Set Binding -> f (Set Binding)
f Set Binding
b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Set Binding -> f (Set Binding)
f Set Binding
c forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Set Binding -> f (Set Binding)
f Set Binding
d

instance Sem.Semigroup BuildInfo where
  BuildInfo Set Binding
w1 Set Binding
x1 Set Binding
y1 Set Binding
z1 <> :: BuildInfo -> BuildInfo -> BuildInfo
<> BuildInfo Set Binding
w2 Set Binding
x2 Set Binding
y2 Set Binding
z2 =
    Set Binding
-> Set Binding -> Set Binding -> Set Binding -> BuildInfo
BuildInfo (Set Binding
w1 forall a. Semigroup a => a -> a -> a
<> Set Binding
w2) (Set Binding
x1 forall a. Semigroup a => a -> a -> a
<> Set Binding
x2) (Set Binding
y1 forall a. Semigroup a => a -> a -> a
<> Set Binding
y2) (Set Binding
z1 forall a. Semigroup a => a -> a -> a
<> Set Binding
z2)

instance Monoid BuildInfo where
  mempty :: BuildInfo
mempty = Set Binding
-> Set Binding -> Set Binding -> Set Binding -> BuildInfo
BuildInfo forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  mappend :: BuildInfo -> BuildInfo -> BuildInfo
mappend = forall a. Semigroup a => a -> a -> a
(Sem.<>)

instance NFData BuildInfo

pPrintBuildInfo :: String -> BuildInfo -> Doc
pPrintBuildInfo :: String -> BuildInfo -> Doc
pPrintBuildInfo String
prefix BuildInfo
bi = [Doc] -> Doc
vcat
  [ String -> Doc -> Set String -> Doc
setattr (String
prefixforall a. [a] -> [a] -> [a]
++String
"HaskellDepends") Doc
empty (forall a s. Getting (Set a) s a -> s -> Set a
setOf (Lens' BuildInfo (Set Binding)
haskellforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
foldedforall b c a. (b -> c) -> (a -> b) -> a -> c
.Lens' Binding Identifier
localNameforall b c a. (b -> c) -> (a -> b) -> a -> c
.Iso' Identifier String
ident) BuildInfo
bi)
  , String -> Doc -> Set String -> Doc
setattr (String
prefixforall a. [a] -> [a] -> [a]
++String
"SystemDepends")  Doc
empty (forall a s. Getting (Set a) s a -> s -> Set a
setOf (Lens' BuildInfo (Set Binding)
systemforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
foldedforall b c a. (b -> c) -> (a -> b) -> a -> c
.Lens' Binding Identifier
localNameforall b c a. (b -> c) -> (a -> b) -> a -> c
.Iso' Identifier String
ident) BuildInfo
bi)
  , String -> Doc -> Set String -> Doc
setattr (String
prefixforall a. [a] -> [a] -> [a]
++String
"PkgconfigDepends") Doc
empty (forall a s. Getting (Set a) s a -> s -> Set a
setOf (Lens' BuildInfo (Set Binding)
pkgconfigforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
foldedforall b c a. (b -> c) -> (a -> b) -> a -> c
.Lens' Binding Identifier
localNameforall b c a. (b -> c) -> (a -> b) -> a -> c
.Iso' Identifier String
ident) BuildInfo
bi)
  , String -> Doc -> Set String -> Doc
setattr (String
prefixforall a. [a] -> [a] -> [a]
++String
"ToolDepends") Doc
empty (forall a s. Getting (Set a) s a -> s -> Set a
setOf (Lens' BuildInfo (Set Binding)
toolforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
foldedforall b c a. (b -> c) -> (a -> b) -> a -> c
.Lens' Binding Identifier
localNameforall b c a. (b -> c) -> (a -> b) -> a -> c
.Iso' Identifier String
ident) BuildInfo
bi)
  ]