{-# LANGUAGE UndecidableInstances #-}
module Hackage.Security.TUF.Mirrors (
Mirrors(..)
, Mirror(..)
, MirrorContent(..)
, MirrorDescription
, describeMirror
) where
import Control.Monad.Except
import Network.URI
import Hackage.Security.JSON
import Hackage.Security.TUF.Header
import Hackage.Security.TUF.Signed
data Mirrors = Mirrors {
mirrorsVersion :: FileVersion
, mirrorsExpires :: FileExpires
, mirrorsMirrors :: [Mirror]
}
data Mirror = Mirror {
mirrorUrlBase :: URI
, mirrorContent :: MirrorContent
}
deriving Show
data MirrorContent =
MirrorFull
deriving Show
instance HasHeader Mirrors where
fileVersion f x = (\y -> x { mirrorsVersion = y }) <$> f (mirrorsVersion x)
fileExpires f x = (\y -> x { mirrorsExpires = y }) <$> f (mirrorsExpires x)
type MirrorDescription = String
describeMirror :: Mirror -> MirrorDescription
describeMirror = show . mirrorUrlBase
instance Monad m => ToJSON m Mirror where
toJSON Mirror{..} = mkObject $ concat [
[ ("urlbase", toJSON mirrorUrlBase) ]
, case mirrorContent of
MirrorFull -> []
]
instance Monad m => ToJSON m Mirrors where
toJSON Mirrors{..} = mkObject [
("_type" , return $ JSString "Mirrorlist")
, ("version" , toJSON mirrorsVersion)
, ("expires" , toJSON mirrorsExpires)
, ("mirrors" , toJSON mirrorsMirrors)
]
instance ReportSchemaErrors m => FromJSON m Mirror where
fromJSON enc = do
mirrorUrlBase <- fromJSField enc "urlbase"
let mirrorContent = MirrorFull
return Mirror{..}
instance ( MonadError DeserializationError m
, ReportSchemaErrors m
) => FromJSON m Mirrors where
fromJSON enc = do
verifyType enc "Mirrorlist"
mirrorsVersion <- fromJSField enc "version"
mirrorsExpires <- fromJSField enc "expires"
mirrorsMirrors <- fromJSField enc "mirrors"
return Mirrors{..}
instance MonadKeys m => FromJSON m (Signed Mirrors) where
fromJSON = signedFromJSON