Distribution/Types/ComponentName.hs

    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric #-}

    module Distribution.Types.ComponentName (
      ComponentName(..),
      defaultLibName,
      libraryComponentName,
      showComponentName,
      componentNameStanza,
      componentNameString,
      ) where

    import Prelude ()
    import Distribution.Compat.Prelude

    import qualified Distribution.Compat.ReadP as Parse
    import Distribution.Compat.ReadP   ((<++))
    import Distribution.Types.UnqualComponentName
    import Distribution.Text

    import Text.PrettyPrint as Disp

    -- Libraries live in a separate namespace, so must distinguish
    data ComponentName = CLibName
                       | CSubLibName UnqualComponentName
                       | CFLibName  UnqualComponentName
                       | CExeName   UnqualComponentName
                       | CTestName  UnqualComponentName
                       | CBenchName UnqualComponentName
                       deriving (Eq, Generic, Ord, Read, Show, Typeable)

    instance Binary ComponentName

    -- Build-target-ish syntax
    instance Text ComponentName where
        disp CLibName = Disp.text "lib"
        disp (CSubLibName str) = Disp.text "lib:" <<>> disp str
        disp (CFLibName str)   = Disp.text "flib:" <<>> disp str
        disp (CExeName str)    = Disp.text "exe:" <<>> disp str
        disp (CTestName str)   = Disp.text "test:" <<>> disp str
        disp (CBenchName str)  = Disp.text "bench:" <<>> disp str

        parse = parseComposite <++ parseSingle
         where
          parseSingle = Parse.string "lib" >> return CLibName
          parseComposite = do
            ctor <- Parse.choice [ Parse.string "lib:" >> return CSubLibName
                                 , Parse.string "flib:" >> return CFLibName
                                 , Parse.string "exe:" >> return CExeName
                                 , Parse.string "bench:" >> return CBenchName
                                 , Parse.string "test:" >> return CTestName ]
            ctor <$> parse

    defaultLibName :: ComponentName
    defaultLibName = CLibName

    showComponentName :: ComponentName -> String
    showComponentName CLibName          = "library"
    showComponentName (CSubLibName name) = "library '" ++ display name ++ "'"
    showComponentName (CFLibName  name) = "foreign library '" ++ display name ++ "'"
    showComponentName (CExeName   name) = "executable '" ++ display name ++ "'"
    showComponentName (CTestName  name) = "test suite '" ++ display name ++ "'"
    showComponentName (CBenchName name) = "benchmark '" ++ display name ++ "'"

    componentNameStanza :: ComponentName -> String
    componentNameStanza CLibName          = "library"
    componentNameStanza (CSubLibName name) = "library " ++ display name
    componentNameStanza (CFLibName  name) = "foreign-library " ++ display name
    componentNameStanza (CExeName   name) = "executable " ++ display name
    componentNameStanza (CTestName  name) = "test-suite " ++ display name
    componentNameStanza (CBenchName name) = "benchmark " ++ display name

    -- | This gets the underlying unqualified component name. In fact, it is
    -- guaranteed to uniquely identify a component, returning
    -- @Nothing@ if the 'ComponentName' was for the public
    -- library.
    componentNameString :: ComponentName -> Maybe UnqualComponentName
    componentNameString CLibName = Nothing
    componentNameString (CSubLibName n) = Just n
    componentNameString (CFLibName  n) = Just n
    componentNameString (CExeName   n) = Just n
    componentNameString (CTestName  n) = Just n
    componentNameString (CBenchName n) = Just n

    -- | Convert the 'UnqualComponentName' of a library into a
    -- 'ComponentName'.
    libraryComponentName :: Maybe UnqualComponentName -> ComponentName
    libraryComponentName Nothing = CLibName
    libraryComponentName (Just n) = CSubLibName n