{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies, FlexibleContexts #-} -- | The base functions for accessing JSON object fields. module Text.JSON.JSONField ( JSONField(..) ) where import Data.ByteString import qualified Data.Trie as T import Text.JSONb import qualified Text.JSON as J import qualified Text.HJson as H import qualified Data.Aeson.Types as A import Text.JSON.Types import Text.JSON.Failure import Control.Failure import qualified Data.Map as M import Data.Text -- | Accessing JSON object fields. class JSONField j f | j -> f where -- | Access the field of a JSON object with potential failure. field :: Failure (NoSuchFieldOrExpectedObject f j) m => f -> j -> m j -- | Access all fields of a JSON object with potential failure. fields :: Failure (ExpectedObject j) m => j -> m [f] -- | Returns all object field values of a JSON value. values :: Failure (ExpectedObject j) m => j -> m [j] instance JSONField JSON ByteString where field f (Object o) = case T.lookup f o of Nothing -> failure (NoSuchFieldOrExpectedObject_NoSuchField f :: NoSuchFieldOrExpectedObject ByteString JSON) Just x -> return x field _ j = failure (NoSuchFieldOrExpectedObject_ExpectedObject j :: NoSuchFieldOrExpectedObject ByteString JSON) fields (Object o) = return (T.keys o) fields j = failure (ExpectedObject j) values (Object o) = return . fmap snd . T.toList $ o values j = failure (ExpectedObject j) instance JSONField J.JSValue [Char] where field f (J.JSObject (JSONObject o)) = case lookup f o of Nothing -> failure (NoSuchFieldOrExpectedObject_NoSuchField f :: NoSuchFieldOrExpectedObject String J.JSValue) Just x -> return x field _ j = failure (NoSuchFieldOrExpectedObject_ExpectedObject j :: NoSuchFieldOrExpectedObject String J.JSValue) fields (J.JSObject (JSONObject o)) = return (fmap fst o) fields j = failure (ExpectedObject j) values (J.JSObject (JSONObject o)) = return (fmap snd o) values j = failure (ExpectedObject j) instance JSONField H.Json [Char] where field f (H.JObject o) = case M.lookup f o of Nothing -> failure (NoSuchFieldOrExpectedObject_NoSuchField f :: NoSuchFieldOrExpectedObject String H.Json) Just x -> return x field _ j = failure (NoSuchFieldOrExpectedObject_ExpectedObject j :: NoSuchFieldOrExpectedObject String H.Json) fields (H.JObject o) = return (M.keys o) fields j = failure (ExpectedObject j) values (H.JObject o) = return (fmap snd (M.toList o)) values j = failure (ExpectedObject j) instance JSONField A.Value Text where field f (A.Object o) = case M.lookup f o of Nothing -> failure (NoSuchFieldOrExpectedObject_NoSuchField f :: NoSuchFieldOrExpectedObject Text A.Value) Just x -> return x field _ j = failure (NoSuchFieldOrExpectedObject_ExpectedObject j :: NoSuchFieldOrExpectedObject Text A.Value) fields (A.Object o) = return (M.keys o) fields j = failure (ExpectedObject j) values (A.Object o) = return (fmap snd (M.toList o)) values j = failure (ExpectedObject j)