content: {-# LANGUAGE OverloadedStrings #-}
  
  module Database.Bloodhound.Internal.Utils.StringlyTyped where
  
  import qualified Data.Text as T
  import Database.Bloodhound.Internal.Utils.Imports
  
  -- This whole module is a sin bucket to deal with Elasticsearch badness.
  newtype StringlyTypedDouble = StringlyTypedDouble
    {unStringlyTypedDouble :: Double}
  
  instance FromJSON StringlyTypedDouble where
    parseJSON =
      fmap StringlyTypedDouble
        . parseJSON
        . unStringlyTypeJSON
  
  newtype StringlyTypedInt = StringlyTypedInt
    {unStringlyTypedInt :: Int}
  
  instance FromJSON StringlyTypedInt where
    parseJSON =
      fmap StringlyTypedInt
        . parseJSON
        . unStringlyTypeJSON
  
  newtype StringlyTypedBool = StringlyTypedBool {unStringlyTypedBool :: Bool}
  
  instance FromJSON StringlyTypedBool where
    parseJSON =
      fmap StringlyTypedBool
        . parseJSON
        . unStringlyTypeJSON
  
  -- | For some reason in several settings APIs, all leaf values get returned
  -- as strings. This function attempts to recover from this for all
  -- non-recursive JSON types. If nothing can be done, the value is left alone.
  unStringlyTypeJSON :: Value -> Value
  unStringlyTypeJSON (String "true") =
    Bool True
  unStringlyTypeJSON (String "false") =
    Bool False
  unStringlyTypeJSON (String "null") =
    Null
  unStringlyTypeJSON v@(String t) =
    case readMay (T.unpack t) of
      Just n -> Number n
      Nothing -> v
  unStringlyTypeJSON v = v
  