Cabal-2.0.0.2: Distribution/Types/UnitId.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Distribution.Types.UnitId
( UnitId, unUnitId, mkUnitId
, DefUnitId
, unsafeMkDefUnitId
, unDefUnitId
, newSimpleUnitId
, mkLegacyUnitId
, getHSLibraryName
, InstalledPackageId -- backwards compat
) where
import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Utils.ShortText
import qualified Distribution.Compat.ReadP as Parse
import Distribution.Text
import Distribution.Types.ComponentId
import Distribution.Types.PackageId
import Text.PrettyPrint (text)
-- | A unit identifier identifies a (possibly instantiated)
-- package/component that can be installed the installed package
-- database. There are several types of components that can be
-- installed:
--
-- * A traditional library with no holes, so that 'unitIdHash'
-- is @Nothing@. In the absence of Backpack, 'UnitId'
-- is the same as a 'ComponentId'.
--
-- * An indefinite, Backpack library with holes. In this case,
-- 'unitIdHash' is still @Nothing@, but in the install,
-- there are only interfaces, no compiled objects.
--
-- * An instantiated Backpack library with all the holes
-- filled in. 'unitIdHash' is a @Just@ a hash of the
-- instantiating mapping.
--
-- A unit is a component plus the additional information on how the
-- holes are filled in. Thus there is a one to many relationship: for a
-- particular component there are many different ways of filling in the
-- holes, and each different combination is a unit (and has a separate
-- 'UnitId').
--
-- 'UnitId' is distinct from 'OpenUnitId', in that it is always
-- installed, whereas 'OpenUnitId' are intermediate unit identities
-- that arise during mixin linking, and don't necessarily correspond
-- to any actually installed unit. Since the mapping is not actually
-- recorded in a 'UnitId', you can't actually substitute over them
-- (but you can substitute over 'OpenUnitId'). See also
-- "Distribution.Backpack.FullUnitId" for a mechanism for expanding an
-- instantiated 'UnitId' to retrieve its mapping.
--
-- Backwards compatibility note: if you need to get the string
-- representation of a UnitId to pass, e.g., as a @-package-id@
-- flag, use the 'display' function, which will work on all
-- versions of Cabal.
--
newtype UnitId = UnitId ShortText
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, NFData)
{-# DEPRECATED InstalledPackageId "Use UnitId instead" #-}
type InstalledPackageId = UnitId
instance Binary UnitId
-- | The textual format for 'UnitId' coincides with the format
-- GHC accepts for @-package-id@.
--
instance Text UnitId where
disp = text . unUnitId
parse = mkUnitId <$> Parse.munch1 (\c -> isAlphaNum c || c `elem` "-_.+")
-- | If you need backwards compatibility, consider using 'display'
-- instead, which is supported by all versions of Cabal.
--
unUnitId :: UnitId -> String
unUnitId (UnitId s) = fromShortText s
mkUnitId :: String -> UnitId
mkUnitId = UnitId . toShortText
-- | 'mkUnitId'
--
-- @since 2.0
instance IsString UnitId where
fromString = mkUnitId
-- | Create a unit identity with no associated hash directly
-- from a 'ComponentId'.
newSimpleUnitId :: ComponentId -> UnitId
newSimpleUnitId = mkUnitId . unComponentId
-- | Make an old-style UnitId from a package identifier.
-- Assumed to be for the public library
mkLegacyUnitId :: PackageId -> UnitId
mkLegacyUnitId = newSimpleUnitId . mkComponentId . display
-- | Returns library name prefixed with HS, suitable for filenames
getHSLibraryName :: UnitId -> String
getHSLibraryName uid = "HS" ++ display uid
-- | A 'UnitId' for a definite package. The 'DefUnitId' invariant says
-- that a 'UnitId' identified this way is definite; i.e., it has no
-- unfilled holes.
newtype DefUnitId = DefUnitId { unDefUnitId :: UnitId }
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, Binary, NFData, Text)
-- | Unsafely create a 'DefUnitId' from a 'UnitId'. Your responsibility
-- is to ensure that the 'DefUnitId' invariant holds.
unsafeMkDefUnitId :: UnitId -> DefUnitId
unsafeMkDefUnitId = DefUnitId