module Ecluse.Core.Json.Lenient (
lenientOptional,
typeMismatchOneOf,
valueKind,
) where
import Data.Aeson (
FromJSON (parseJSON),
Object,
Value (Array, Bool, Null, Number, Object, String),
(.:?),
)
import Data.Aeson.Key (Key)
import Data.Aeson.Types (Parser, parseMaybe)
lenientOptional :: (FromJSON a, NFData a) => Object -> Key -> Parser (Maybe a)
lenientOptional :: forall a.
(FromJSON a, NFData a) =>
Object -> Key -> Parser (Maybe a)
lenientOptional Object
o Key
k = do
mv <- Object
o Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
k
pure $ case mv >>= parseMaybe parseJSON of
Just a
value -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. NFData a => (a -> b) -> a -> b
$!! a
value
Maybe a
Nothing -> Maybe a
forall a. Maybe a
Nothing
typeMismatchOneOf :: String -> Value -> Parser a
typeMismatchOneOf :: forall a. String -> Value -> Parser a
typeMismatchOneOf String
expected Value
actual =
String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"expected " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
expected String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
", but encountered " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Value -> String
valueKind Value
actual)
valueKind :: Value -> String
valueKind :: Value -> String
valueKind = \case
Object{} -> String
"an object"
String{} -> String
"a string"
Array{} -> String
"an array"
Number{} -> String
"a number"
Bool{} -> String
"a boolean"
Value
Null -> String
"null"