module Distribution.Hackage.DB.Parsed
( Hackage, readHackage, readHackage', parseHackage
, parseUnparsedHackage
, parsePackage, parsePackage'
)
where
import Data.ByteString.Lazy.Char8 ( ByteString )
import Data.Map
import Data.String.UTF8 ( toString, fromRep )
import Data.Version
import qualified Distribution.Hackage.DB.Unparsed as Unparsed
import Distribution.PackageDescription
import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
import Distribution.Text ( display )
type Hackage = Map String (Map Version GenericPackageDescription)
readHackage :: IO Hackage
readHackage = fmap parseUnparsedHackage Unparsed.readHackage
readHackage' :: FilePath -> IO Hackage
readHackage' = fmap parseUnparsedHackage . Unparsed.readHackage'
parseHackage :: ByteString -> Hackage
parseHackage = parseUnparsedHackage . Unparsed.parseHackage
parseUnparsedHackage :: Unparsed.Hackage -> Hackage
parseUnparsedHackage = Data.Map.mapWithKey parsePackages
where
parsePackages :: String -> Map Version ByteString -> Map Version GenericPackageDescription
parsePackages name = Data.Map.mapWithKey (parsePackage name)
parsePackage :: String -> Version -> ByteString -> GenericPackageDescription
parsePackage name version buf = case parsePackage' buf of
Right a -> a
Left err -> error $ "cannot parse cabal package " ++ show name ++ "-" ++ display version ++ ": " ++ err
parsePackage' :: ByteString -> Either String GenericPackageDescription
parsePackage' buf = case parsePackageDescription (decodeUTF8 buf) of
ParseOk _ a -> Right a
ParseFailed err -> Left (show err)
where
decodeUTF8 :: ByteString -> String
decodeUTF8 = toString . fromRep