{-# LANGUAGE TupleSections, Rank2Types #-}

module CabalLenses.Traversals.Internal
   ( traverseDataIf
   , traverseData
   , traverseDependencyIf
   , traverseDependency
   ) where

import CabalLenses.CondVars (CondVars)
import qualified CabalLenses.CondVars as CV
import Distribution.Types.CondTree (CondTree(..), CondBranch(..))
import Distribution.PackageDescription (ConfVar)
import Distribution.Package (Dependency(..))
import Control.Lens (Traversal')

type CondTree' a = CondTree ConfVar [Dependency] a


-- | A traversal for all 'condTreeData' of 'CondTree' that match 'CondVars'.
traverseDataIf :: CondVars -> Traversal' (CondTree' dat) dat
traverseDataIf :: forall dat. CondVars -> Traversal' (CondTree' dat) dat
traverseDataIf CondVars
condVars dat -> f dat
f (CondNode dat
dat [Dependency]
constr [CondBranch ConfVar [Dependency] dat]
comps) =
   forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> dat -> f dat
f dat
dat
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure [Dependency]
constr
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {f :: * -> *} {a}.
Applicative f =>
CondVars
-> (a -> f a)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseCompIf CondVars
condVars) dat -> f dat
f [CondBranch ConfVar [Dependency] dat]
comps
   where
      traverseCompIf :: CondVars
-> (a -> f a)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseCompIf CondVars
condVars a -> f a
f (CondBranch Condition ConfVar
cond CondTree ConfVar [Dependency] a
ifComp Maybe (CondTree ConfVar [Dependency] a)
elseComp) =
         forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure Condition ConfVar
cond forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f (CondTree ConfVar [Dependency] a)
ifComp' forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f (Maybe (CondTree ConfVar [Dependency] a))
elseComp'
         where
            ifComp' :: f (CondTree ConfVar [Dependency] a)
ifComp' | Bool
condMatches = forall dat. CondVars -> Traversal' (CondTree' dat) dat
traverseDataIf CondVars
condVars a -> f a
f CondTree ConfVar [Dependency] a
ifComp
                    | Bool
otherwise   = forall (f :: * -> *) a. Applicative f => a -> f a
pure CondTree ConfVar [Dependency] a
ifComp

            elseComp' :: f (Maybe (CondTree ConfVar [Dependency] a))
elseComp' | Bool
condMatches = forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CondTree ConfVar [Dependency] a)
elseComp
                      | Bool
otherwise   = (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall dat. CondVars -> Traversal' (CondTree' dat) dat
traverseDataIf CondVars
condVars) a -> f a
f Maybe (CondTree ConfVar [Dependency] a)
elseComp

            condMatches :: Bool
condMatches = CondVars -> Condition ConfVar -> Bool
CV.eval CondVars
condVars Condition ConfVar
cond


-- | A traversal for all 'condTreeData' (the if and else branches) of the 'CondTree'.
traverseData :: Traversal' (CondTree' dat) dat
traverseData :: forall dat. Traversal' (CondTree' dat) dat
traverseData dat -> f dat
f (CondNode dat
dat [Dependency]
constr [CondBranch ConfVar [Dependency] dat]
comps) =
   forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> dat -> f dat
f dat
dat
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure [Dependency]
constr
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {f :: * -> *} {a}.
Applicative f =>
(a -> f a)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseComp) dat -> f dat
f [CondBranch ConfVar [Dependency] dat]
comps
   where
      traverseComp :: (a -> f a)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseComp a -> f a
f (CondBranch Condition ConfVar
cond CondTree ConfVar [Dependency] a
ifComp Maybe (CondTree ConfVar [Dependency] a)
elseComp) =
         forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure Condition ConfVar
cond
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall dat. Traversal' (CondTree' dat) dat
traverseData a -> f a
f CondTree ConfVar [Dependency] a
ifComp
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall dat. Traversal' (CondTree' dat) dat
traverseData) a -> f a
f Maybe (CondTree ConfVar [Dependency] a)
elseComp


-- | A traversal for all 'condTreeConstraints' of 'CondTree' that match 'CondVars'.
traverseDependencyIf :: CondVars -> Traversal' (CondTree' dat) Dependency
traverseDependencyIf :: forall dat. CondVars -> Traversal' (CondTree' dat) Dependency
traverseDependencyIf CondVars
condVars Dependency -> f Dependency
f (CondNode dat
dat [Dependency]
constr [CondBranch ConfVar [Dependency] dat]
comps) =
   forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure dat
dat
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Dependency -> f Dependency
f [Dependency]
constr
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {f :: * -> *} {a}.
Applicative f =>
CondVars
-> (Dependency -> f Dependency)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseCompIf CondVars
condVars) Dependency -> f Dependency
f [CondBranch ConfVar [Dependency] dat]
comps
   where
      traverseCompIf :: CondVars
-> (Dependency -> f Dependency)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseCompIf CondVars
condVars Dependency -> f Dependency
f (CondBranch Condition ConfVar
cond CondTree ConfVar [Dependency] a
ifComp Maybe (CondTree ConfVar [Dependency] a)
elseComp) =
         forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure Condition ConfVar
cond forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f (CondTree ConfVar [Dependency] a)
ifComp' forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f (Maybe (CondTree ConfVar [Dependency] a))
elseComp'
         where
            ifComp' :: f (CondTree ConfVar [Dependency] a)
ifComp' | Bool
condMatches = forall dat. CondVars -> Traversal' (CondTree' dat) Dependency
traverseDependencyIf CondVars
condVars Dependency -> f Dependency
f CondTree ConfVar [Dependency] a
ifComp
                    | Bool
otherwise   = forall (f :: * -> *) a. Applicative f => a -> f a
pure CondTree ConfVar [Dependency] a
ifComp

            elseComp' :: f (Maybe (CondTree ConfVar [Dependency] a))
elseComp' | Bool
condMatches = forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CondTree ConfVar [Dependency] a)
elseComp
                      | Bool
otherwise   = (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall dat. CondVars -> Traversal' (CondTree' dat) Dependency
traverseDependencyIf CondVars
condVars) Dependency -> f Dependency
f Maybe (CondTree ConfVar [Dependency] a)
elseComp

            condMatches :: Bool
condMatches = CondVars -> Condition ConfVar -> Bool
CV.eval CondVars
condVars Condition ConfVar
cond


-- | A traversal for all 'condTreeConstraints' (the if and else branches) of the 'CondTree'.
traverseDependency :: Traversal' (CondTree' dat) Dependency
traverseDependency :: forall dat. Traversal' (CondTree' dat) Dependency
traverseDependency Dependency -> f Dependency
f (CondNode dat
dat [Dependency]
constr [CondBranch ConfVar [Dependency] dat]
comps) =
   forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure dat
dat
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Dependency -> f Dependency
f [Dependency]
constr
            forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {f :: * -> *} {a}.
Applicative f =>
(Dependency -> f Dependency)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseComp) Dependency -> f Dependency
f [CondBranch ConfVar [Dependency] dat]
comps
   where
      traverseComp :: (Dependency -> f Dependency)
-> CondBranch ConfVar [Dependency] a
-> f (CondBranch ConfVar [Dependency] a)
traverseComp Dependency -> f Dependency
f (CondBranch Condition ConfVar
cond CondTree ConfVar [Dependency] a
ifComp Maybe (CondTree ConfVar [Dependency] a)
elseComp) =
         forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (f :: * -> *) a. Applicative f => a -> f a
pure Condition ConfVar
cond
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall dat. Traversal' (CondTree' dat) Dependency
traverseDependency Dependency -> f Dependency
f CondTree ConfVar [Dependency] a
ifComp
                    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall dat. Traversal' (CondTree' dat) Dependency
traverseDependency) Dependency -> f Dependency
f Maybe (CondTree ConfVar [Dependency] a)
elseComp