module Bloodhound.Import
  ( module X,
    LByteString,
    Method,
    omitNulls,
    parseNEJSON,
    parseReadText,
    readMay,
    showText,
    deleteSeveral,
    oPath,
    tshow,
  )
where

import Control.Applicative as X (Alternative (..), optional)
import Control.Exception as X (Exception)
import Control.Monad as X (MonadPlus (..), forM, (<=<))
import Control.Monad.Catch as X
  ( MonadCatch,
    MonadMask,
    MonadThrow,
  )
import Control.Monad.Except as X (MonadError)
import Control.Monad.Fix as X (MonadFix)
import Control.Monad.IO.Class as X (MonadIO (..))
import Control.Monad.Reader as X
  ( MonadReader (..),
    MonadTrans (..),
    ReaderT (..),
  )
import Control.Monad.State as X (MonadState)
import Control.Monad.Writer as X (MonadWriter)
import Data.Aeson as X
import Data.Aeson.Key as X
import qualified Data.Aeson.KeyMap as X
import Data.Aeson.Types as X
  ( Pair,
    Parser,
    emptyObject,
    parseEither,
    parseMaybe,
    typeMismatch,
  )
import Data.Bifunctor as X (first)
import qualified Data.ByteString.Lazy as BL
import Data.Char as X (isNumber)
import Data.Hashable as X (Hashable)
import Data.List as X (foldl', intercalate, nub)
import Data.List.NonEmpty as X (NonEmpty (..), toList)
import Data.Maybe as X
  ( catMaybes,
    fromMaybe,
    isNothing,
    maybeToList,
  )
import Data.Scientific as X (Scientific)
import Data.Semigroup as X (Semigroup (..))
import Data.Text as X (Text)
import qualified Data.Text as T
import Data.Time.Calendar as X (Day (..), showGregorian)
import Data.Time.Clock as X (NominalDiffTime, UTCTime)
import Data.Time.Clock.POSIX as X
import qualified Data.Traversable as DT
import qualified Data.Vector as V
import qualified Network.HTTP.Types.Method as NHTM

type LByteString = BL.ByteString

type Method = NHTM.Method

readMay :: Read a => String -> Maybe a
readMay :: forall a. Read a => String -> Maybe a
readMay String
s = case forall a. Read a => ReadS a
reads String
s of
  (a
a, String
"") : [(a, String)]
_ -> forall a. a -> Maybe a
Just a
a
  [(a, String)]
_ -> forall a. Maybe a
Nothing

parseReadText :: Read a => Text -> Parser a
parseReadText :: forall a. Read a => Text -> Parser a
parseReadText = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall (m :: * -> *) a. MonadPlus m => m a
mzero forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Read a => String -> Maybe a
readMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack

showText :: Show a => a -> Text
showText :: forall a. Show a => a -> Text
showText = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

omitNulls :: [(Key, Value)] -> Value
omitNulls :: [(Key, Value)] -> Value
omitNulls = [(Key, Value)] -> Value
object forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter forall {a}. (a, Value) -> Bool
notNull
  where
    notNull :: (a, Value) -> Bool
notNull (a
_, Value
Null) = Bool
False
    notNull (a
_, Array Array
a) = (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Bool
V.null) Array
a
    notNull (a, Value)
_ = Bool
True

parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
parseNEJSON :: forall a. FromJSON a => [Value] -> Parser (NonEmpty a)
parseNEJSON [] = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected non-empty list"
parseNEJSON (Value
x : [Value]
xs) = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
DT.mapM forall a. FromJSON a => Value -> Parser a
parseJSON (Value
x forall a. a -> [a] -> NonEmpty a
:| [Value]
xs)

deleteSeveral :: [Key] -> X.KeyMap v -> X.KeyMap v
deleteSeveral :: forall v. [Key] -> KeyMap v -> KeyMap v
deleteSeveral [Key]
ks KeyMap v
km = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall v. Key -> KeyMap v -> KeyMap v
X.delete KeyMap v
km [Key]
ks

oPath :: ToJSON a => NonEmpty Key -> a -> Value
oPath :: forall a. ToJSON a => NonEmpty Key -> a -> Value
oPath (Key
k :| []) a
v = [(Key, Value)] -> Value
object [Key
k forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= a
v]
oPath (Key
k :| (Key
h : [Key]
t)) a
v = [(Key, Value)] -> Value
object [Key
k forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => NonEmpty Key -> a -> Value
oPath (Key
h forall a. a -> [a] -> NonEmpty a
:| [Key]
t) a
v]

tshow :: Show a => a -> Text
tshow :: forall a. Show a => a -> Text
tshow = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show