forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGhcPkgId.hs
More file actions
81 lines (65 loc) · 2.14 KB
/
Copy pathGhcPkgId.hs
File metadata and controls
81 lines (65 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{-# LANGUAGE NoImplicitPrelude #-}
-- | A ghc-pkg id.
module Stack.Types.GhcPkgId
( GhcPkgId
, unGhcPkgId
, ghcPkgIdParser
, parseGhcPkgId
, ghcPkgIdString
) where
import Data.Aeson.Types ( FromJSON (..), ToJSON (..), withText )
import Data.Attoparsec.Text
( Parser, choice, digit, endOfInput, letter, many1, parseOnly
, satisfy
)
import qualified Data.Text as T
import Database.Persist.Sql ( PersistField, PersistFieldSql )
import Prelude ( Read (..) )
import Stack.Prelude
-- | A parse fail.
newtype GhcPkgIdParseFail
= GhcPkgIdParseFail Text
deriving (Show, Typeable)
instance Exception GhcPkgIdParseFail where
displayException (GhcPkgIdParseFail bs) = concat
[ "Error: [S-5359]\n"
, "Invalid package ID: "
, show bs
]
-- | A ghc-pkg package identifier.
newtype GhcPkgId
= GhcPkgId Text
deriving (Data, Eq, Generic, Ord, PersistField, PersistFieldSql, Typeable)
instance Hashable GhcPkgId
instance NFData GhcPkgId
instance Show GhcPkgId where
show = show . ghcPkgIdString
instance Read GhcPkgId where
readsPrec i = map (first (GhcPkgId . T.pack)) . readsPrec i
instance FromJSON GhcPkgId where
parseJSON = withText "GhcPkgId" $ \t ->
case parseGhcPkgId t of
Left e -> fail $ show (e, t)
Right x -> pure x
instance ToJSON GhcPkgId where
toJSON g =
toJSON (ghcPkgIdString g)
-- | Convenient way to parse a package name from a 'Text'.
parseGhcPkgId :: MonadThrow m => Text -> m GhcPkgId
parseGhcPkgId x = go x
where
go = either
(const (throwM (GhcPkgIdParseFail x)))
pure . parseOnly (ghcPkgIdParser <* endOfInput)
-- | A parser for a package-version-hash pair.
ghcPkgIdParser :: Parser GhcPkgId
ghcPkgIdParser =
let elements = "_.-" :: String
in GhcPkgId . T.pack <$>
many1 (choice [digit, letter, satisfy (`elem` elements)])
-- | Get a string representation of GHC package id.
ghcPkgIdString :: GhcPkgId -> String
ghcPkgIdString (GhcPkgId x) = T.unpack x
-- | Get a text value of GHC package id
unGhcPkgId :: GhcPkgId -> Text
unGhcPkgId (GhcPkgId v) = v