{-# LANGUAGE DeriveGeneric #-} {- | Maintainer: simons@cryp.to Stability: provisional Portability: portable Types and class instances for parsing the @package.json@ files found in a @01-index.tar@ tarball from Hackage with "Data.Aeson". These parsers mirror the exact structure of those files, but only a small part of it is actually of interest to anyone other than implementors of @cabal-install@. Everyone else will most likely prefer the functions oferred by "Distribution.Hackage.DB.Parsed". -} module Distribution.Hackage.DB.MetaData where import Distribution.Hackage.DB.Errors import Control.Exception import Data.Aeson import Data.ByteString.Lazy.UTF8 as BS import Data.Map as Map import GHC.Generics ( Generic ) -- | Parse the @package.json@ file found in a @01-index.tar@ tarball from -- Hackage with "Data.Aeson". This function is a convenience wrapper around -- 'eitherDecode' that throws an 'InvalidMetaFile' exception to signal failure. -- -- >>> :set -XOverloadedStrings -- >>> parseMetaData "{\"signatures\":[],\"signed\":{\"_type\":\"Targets\",\"expires\":null,\"targets\":{\"<repo>/package/jailbreak-cabal-1.3.2.tar.gz\":{\"hashes\":{\"md5\":\"ba42b3e68323ccbeb3ac900cd68f9e90\",\"sha256\":\"212a8bbc3dfc748c4063282414a2726709d651322f3984c9989179d2352950f4\"},\"length\":2269}},\"version\":0}}" -- MetaData {signed = SignedMetaData {version = 0, expires = Nothing, _type = "Targets", targets = fromList [("<repo>/package/jailbreak-cabal-1.3.2.tar.gz",TargetData {length = 2269, hashes = fromList [("md5","ba42b3e68323ccbeb3ac900cd68f9e90"),("sha256","212a8bbc3dfc748c4063282414a2726709d651322f3984c9989179d2352950f4")]})]}, signatures = []} -- >>> parseMetaData "{}" -- *** Exception: InvalidMetaFile "Error in $: key \"signed\" not present" -- >>> parseMetaData "" -- *** Exception: InvalidMetaFile "Error in $: not enough input" parseMetaData :: ByteString -> MetaData parseMetaData = either (throw . InvalidMetaFile) id . eitherDecode data MetaData = MetaData { signed :: SignedMetaData , signatures :: [String] } deriving (Show, Generic) instance FromJSON MetaData data SignedMetaData = SignedMetaData { version :: Int , expires :: Maybe String , _type :: String , targets :: Map String TargetData } deriving (Show, Generic) instance FromJSON SignedMetaData data TargetData = TargetData { length :: Int , hashes :: Map String String } deriving (Show, Generic) instance FromJSON TargetData