{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
module Distribution.Client.Types.PackageSpecifier (
    PackageSpecifier (..),
    pkgSpecifierTarget,
    pkgSpecifierConstraints,
) where

import Distribution.Client.Compat.Prelude
import Prelude ()

import Distribution.Package           (Package (..), packageName, packageVersion)
import Distribution.Types.PackageName (PackageName)
import Distribution.Version           (thisVersion)

import Distribution.Solver.Types.ConstraintSource
import Distribution.Solver.Types.LabeledPackageConstraint
import Distribution.Solver.Types.PackageConstraint

-- | A fully or partially resolved reference to a package.
--
data PackageSpecifier pkg =

     -- | A partially specified reference to a package (either source or
     -- installed). It is specified by package name and optionally some
     -- required properties. Use a dependency resolver to pick a specific
     -- package satisfying these properties.
     --
     NamedPackage PackageName [PackageProperty]

     -- | A fully specified source package.
     --
   | SpecificSourcePackage pkg
  deriving (PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
(PackageSpecifier pkg -> PackageSpecifier pkg -> Bool)
-> (PackageSpecifier pkg -> PackageSpecifier pkg -> Bool)
-> Eq (PackageSpecifier pkg)
forall pkg.
Eq pkg =>
PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
$c/= :: forall pkg.
Eq pkg =>
PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
== :: PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
$c== :: forall pkg.
Eq pkg =>
PackageSpecifier pkg -> PackageSpecifier pkg -> Bool
Eq, Int -> PackageSpecifier pkg -> ShowS
[PackageSpecifier pkg] -> ShowS
PackageSpecifier pkg -> String
(Int -> PackageSpecifier pkg -> ShowS)
-> (PackageSpecifier pkg -> String)
-> ([PackageSpecifier pkg] -> ShowS)
-> Show (PackageSpecifier pkg)
forall pkg. Show pkg => Int -> PackageSpecifier pkg -> ShowS
forall pkg. Show pkg => [PackageSpecifier pkg] -> ShowS
forall pkg. Show pkg => PackageSpecifier pkg -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PackageSpecifier pkg] -> ShowS
$cshowList :: forall pkg. Show pkg => [PackageSpecifier pkg] -> ShowS
show :: PackageSpecifier pkg -> String
$cshow :: forall pkg. Show pkg => PackageSpecifier pkg -> String
showsPrec :: Int -> PackageSpecifier pkg -> ShowS
$cshowsPrec :: forall pkg. Show pkg => Int -> PackageSpecifier pkg -> ShowS
Show, a -> PackageSpecifier b -> PackageSpecifier a
(a -> b) -> PackageSpecifier a -> PackageSpecifier b
(forall a b. (a -> b) -> PackageSpecifier a -> PackageSpecifier b)
-> (forall a b. a -> PackageSpecifier b -> PackageSpecifier a)
-> Functor PackageSpecifier
forall a b. a -> PackageSpecifier b -> PackageSpecifier a
forall a b. (a -> b) -> PackageSpecifier a -> PackageSpecifier b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> PackageSpecifier b -> PackageSpecifier a
$c<$ :: forall a b. a -> PackageSpecifier b -> PackageSpecifier a
fmap :: (a -> b) -> PackageSpecifier a -> PackageSpecifier b
$cfmap :: forall a b. (a -> b) -> PackageSpecifier a -> PackageSpecifier b
Functor, (forall x. PackageSpecifier pkg -> Rep (PackageSpecifier pkg) x)
-> (forall x. Rep (PackageSpecifier pkg) x -> PackageSpecifier pkg)
-> Generic (PackageSpecifier pkg)
forall x. Rep (PackageSpecifier pkg) x -> PackageSpecifier pkg
forall x. PackageSpecifier pkg -> Rep (PackageSpecifier pkg) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall pkg x. Rep (PackageSpecifier pkg) x -> PackageSpecifier pkg
forall pkg x. PackageSpecifier pkg -> Rep (PackageSpecifier pkg) x
$cto :: forall pkg x. Rep (PackageSpecifier pkg) x -> PackageSpecifier pkg
$cfrom :: forall pkg x. PackageSpecifier pkg -> Rep (PackageSpecifier pkg) x
Generic)

instance Binary pkg => Binary (PackageSpecifier pkg)
instance Structured pkg => Structured (PackageSpecifier pkg)

pkgSpecifierTarget :: Package pkg => PackageSpecifier pkg -> PackageName
pkgSpecifierTarget :: PackageSpecifier pkg -> PackageName
pkgSpecifierTarget (NamedPackage PackageName
name [PackageProperty]
_)       = PackageName
name
pkgSpecifierTarget (SpecificSourcePackage pkg
pkg) = pkg -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName pkg
pkg

pkgSpecifierConstraints :: Package pkg
                        => PackageSpecifier pkg -> [LabeledPackageConstraint]
pkgSpecifierConstraints :: PackageSpecifier pkg -> [LabeledPackageConstraint]
pkgSpecifierConstraints (NamedPackage PackageName
name [PackageProperty]
props) = (PackageProperty -> LabeledPackageConstraint)
-> [PackageProperty] -> [LabeledPackageConstraint]
forall a b. (a -> b) -> [a] -> [b]
map PackageProperty -> LabeledPackageConstraint
toLpc [PackageProperty]
props
  where
    toLpc :: PackageProperty -> LabeledPackageConstraint
toLpc PackageProperty
prop = PackageConstraint -> ConstraintSource -> LabeledPackageConstraint
LabeledPackageConstraint
                 (ConstraintScope -> PackageProperty -> PackageConstraint
PackageConstraint (PackageName -> ConstraintScope
scopeToplevel PackageName
name) PackageProperty
prop)
                 ConstraintSource
ConstraintSourceUserTarget
pkgSpecifierConstraints (SpecificSourcePackage pkg
pkg)  =
    [PackageConstraint -> ConstraintSource -> LabeledPackageConstraint
LabeledPackageConstraint PackageConstraint
pc ConstraintSource
ConstraintSourceUserTarget]
  where
    pc :: PackageConstraint
pc = ConstraintScope -> PackageProperty -> PackageConstraint
PackageConstraint
         (PackageName -> ConstraintScope
ScopeTarget (PackageName -> ConstraintScope) -> PackageName -> ConstraintScope
forall a b. (a -> b) -> a -> b
$ pkg -> PackageName
forall pkg. Package pkg => pkg -> PackageName
packageName pkg
pkg)
         (VersionRange -> PackageProperty
PackagePropertyVersion (VersionRange -> PackageProperty)
-> VersionRange -> PackageProperty
forall a b. (a -> b) -> a -> b
$ Version -> VersionRange
thisVersion (pkg -> Version
forall pkg. Package pkg => pkg -> Version
packageVersion pkg
pkg))