2019-04-17 12:48:41 +03:00
|
|
|
module Data.Aeson.Extended
|
2022-03-23 23:23:46 +03:00
|
|
|
( FromJSONKeyValue (..),
|
2021-09-24 01:56:37 +03:00
|
|
|
ToJSONKeyValue (..),
|
2022-04-29 05:13:13 +03:00
|
|
|
FromJSONWithContext (..),
|
2021-11-11 18:55:32 +03:00
|
|
|
mapWithJSONPath,
|
2022-03-23 23:23:46 +03:00
|
|
|
encodeToStrictText,
|
|
|
|
(.=?),
|
|
|
|
|
|
|
|
-- * Re-exports
|
|
|
|
module Data.Aeson,
|
2021-09-24 01:56:37 +03:00
|
|
|
)
|
|
|
|
where
|
2019-04-17 12:48:41 +03:00
|
|
|
|
2022-03-23 23:23:46 +03:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
import Data.Aeson
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.Aeson.Text (encodeToTextBuilder)
|
2021-11-11 18:55:32 +03:00
|
|
|
import Data.Aeson.Types (JSONPathElement (..), Parser)
|
2022-03-23 23:23:46 +03:00
|
|
|
import Data.Functor.Const (getConst)
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.Text.Lazy (toStrict)
|
|
|
|
import Data.Text.Lazy.Builder (toLazyText)
|
|
|
|
import Hasura.Prelude
|
2019-04-17 12:48:41 +03:00
|
|
|
|
2022-03-23 23:23:46 +03:00
|
|
|
-------------------------------------------------------------------------------
|
2021-03-25 20:50:08 +03:00
|
|
|
|
|
|
|
class ToJSONKeyValue a where
|
2022-06-08 18:31:28 +03:00
|
|
|
toJSONKeyValue :: a -> (Key, Value)
|
2021-03-25 20:50:08 +03:00
|
|
|
|
|
|
|
class FromJSONKeyValue a where
|
2022-06-08 18:31:28 +03:00
|
|
|
parseJSONKeyValue :: (Key, Value) -> Parser a
|
2021-03-25 20:50:08 +03:00
|
|
|
|
|
|
|
instance ToJSONKeyValue Void where
|
|
|
|
toJSONKeyValue = absurd
|
|
|
|
|
|
|
|
instance ToJSONKeyValue a => ToJSONKeyValue (Const a b) where
|
|
|
|
toJSONKeyValue = toJSONKeyValue . getConst
|
2021-11-11 18:55:32 +03:00
|
|
|
|
2022-04-29 05:13:13 +03:00
|
|
|
-- | Similar to 'FromJSON', except the parser can also source data with which
|
|
|
|
-- to construct 'a' from a context 'ctx'.
|
|
|
|
--
|
|
|
|
-- This can be useful if the 'a' value contains some data that is not from the
|
|
|
|
-- current piece of JSON (the 'Value'). For example, some data from higher
|
|
|
|
-- up in the overall JSON graph, or from some system context.
|
|
|
|
class FromJSONWithContext ctx a | a -> ctx where
|
|
|
|
parseJSONWithContext :: ctx -> Value -> Parser a
|
|
|
|
|
2022-03-23 23:23:46 +03:00
|
|
|
-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- | An optional key-value pair for encoding a JSON object.
|
|
|
|
--
|
|
|
|
-- @
|
|
|
|
-- object $ ["foo" .= 0] <> catMaybes [ "bar" .=? Nothing, "baz" .=? 2 ]
|
|
|
|
-- @
|
2022-06-08 18:31:28 +03:00
|
|
|
(.=?) :: (ToJSON v, KeyValue kv) => Key -> Maybe v -> Maybe kv
|
2022-03-23 23:23:46 +03:00
|
|
|
(.=?) k = fmap (k .=)
|
|
|
|
{-# INLINE (.=?) #-}
|
|
|
|
|
|
|
|
infixr 8 .=?
|
|
|
|
|
|
|
|
-- | Map a 'Parser' over a list, keeping the JSONPath context
|
2021-11-11 18:55:32 +03:00
|
|
|
mapWithJSONPath :: (a -> Parser b) -> [a] -> Parser [b]
|
|
|
|
mapWithJSONPath parser xs =
|
|
|
|
traverse (\(idx, item) -> parser item <?> Index idx) $ zip [0 ..] xs
|
2022-03-23 23:23:46 +03:00
|
|
|
|
|
|
|
encodeToStrictText :: ToJSON a => a -> Text
|
|
|
|
encodeToStrictText = toStrict . toLazyText . encodeToTextBuilder
|