{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Hercules.Formats.Common where
import Control.Monad
import Data.Aeson
( (.:),
(.:?),
)
import Data.Aeson.Types
( Object,
Parser,
Value,
withObject,
)
import Data.Coerce (coerce)
import qualified Data.List
import Data.Text (Text)
import qualified Data.Text as T
import Prelude
withKind :: Text -> (Object -> Parser a) -> Value -> Parser a
withKind k f = withObject (T.unpack k) $ \o -> do
k' <- o .: "kind"
when (k' /= k) $ fail $ "kind field must be " <> show k <> ", not " <> show k'
f o
newtype VersionParser a
= VersionParser
{ fromVersionParser :: (Maybe Text, Object -> Parser a)
}
deriving (Functor)
noVersion :: (Object -> Parser a) -> VersionParser a
noVersion = VersionParser . (Nothing,)
version :: Text -> (Object -> Parser a) -> VersionParser a
version t p = VersionParser (Just t, p)
withVersions :: forall a. [VersionParser a] -> Object -> Parser a
withVersions vps' o = do
let vps = coerce vps' :: [(Maybe Text, Object -> Parser a)]
v <- o .:? "apiVersion"
case Data.List.lookup v vps of
Just p -> p o
Nothing ->
let vs = map fst vps
in case vs of
[Nothing] -> fail "Unexpected apiVersion field. "
_ ->
fail $
"Expected apiVersion to be one of "
<> unwords
(map showVersion vs)
where
showVersion Nothing = "<no version field>"
showVersion (Just t) = show t