{-| Module : Network.Nakadi.Internal.Types.Problem Description : Nakadi Client Problem Type (Internal) Copyright : (c) Moritz Schulte 2017 License : BSD3 Maintainer : mtesseract@silverratio.net Stability : experimental Portability : POSIX Implementation of the error object described in RFC7807. -} {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StrictData #-} {-# LANGUAGE TupleSections #-} module Network.Nakadi.Internal.Types.Problem where import Data.Aeson import Data.HashMap.Lazy (HashMap) import Data.Int import Data.Text (Text) import Prelude import qualified Data.HashMap.Lazy as HashMap import Data.Maybe import GHC.Generics -- | Type for RFC7807 @Problem@ objects. data Problem = Problem { problemType :: Text , problemTitle :: Text , problemStatus :: Int32 , problemDetail :: Maybe Text , problemInstance :: Maybe Text , problemCustom :: Maybe (HashMap Text Value) } deriving (Show, Eq, Generic) instance ToJSON Problem where toJSON Problem { .. } = let hm = HashMap.fromList ([ ("type", String problemType) , ("title", String problemTitle) , ("status", Number (fromIntegral problemStatus)) ] ++ catMaybes [ ("detail",) . String <$> problemDetail , ("instance",) . String <$> problemInstance ]) in Object (maybe hm (HashMap.union hm) problemCustom) instance FromJSON Problem where parseJSON = withObject "Problem" $ \obj -> do let custom = HashMap.filterWithKey (\ k _ -> k `notElem` ["type", "title", "status"]) obj type' <- obj .: "type" title <- obj .: "title" status <- obj .: "status" detail <- obj .:? "detail" instance' <- obj .:? "instance" pure Problem { problemType = type' , problemTitle = title , problemStatus = status , problemDetail = detail , problemInstance = instance' , problemCustom = if HashMap.null custom then Nothing else Just custom }