{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}

-- | 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 Text.JSON.Types

class JSONField j f | j -> f where
  field ::
    f
    -> j
    -> Maybe j
  fields ::
    j
    -> Maybe [f]
  -- | Returns the potential object field values of a JSON value.
  values ::
    j
    -> Maybe [j]

instance JSONField JSON ByteString where
  field f (Object o) =
    T.lookup f o
  field _ _ =
    Nothing
  fields (Object o) =
    Just (T.keys o)
  fields _ =
    Nothing
  values (Object o) =
    Just . fmap snd . T.toList $ o
  values _ =
    Nothing

instance JSONField J.JSValue [Char] where
  field f (J.JSObject (JSONObject o)) =
    lookup f o
  field _ _ =
    Nothing
  fields (J.JSObject (JSONObject o)) =
    Just (fmap fst o)
  fields _ =
    Nothing
  values (J.JSObject (JSONObject o)) =
    Just (fmap snd o)
  values _ =
    Nothing