    {-# LANGUAGE RecordWildCards #-}
    module Data.Aeson.JSONPath.Query.Query
      ( qQuery
      , qQueryLocated
      )
      where

    import Control.Monad                   (join)
    import Data.Aeson                      (Value)
    import Data.Vector                     (Vector)

    import qualified Data.Vector           as V

    import Data.Aeson.JSONPath.Types
    import Data.Aeson.JSONPath.Query.Segment

    import Prelude

    -- | Runs the JSONPath Query
    qQuery :: Query -> QueryState -> Vector Value
    qQuery :: Query -> QueryState -> Vector Value
    qQuery Query{[QuerySegment Query]
    QueryType
    queryType :: QueryType
    querySegments :: [QuerySegment Query]
    querySegments :: Query -> [QuerySegment Query]
    queryType :: Query -> QueryType
    ..} qS :: QueryState
    qS@QueryState{Value
    Query -> QueryState -> Vector Value
    rootVal :: Value
    curVal :: Value
    executeQuery :: Query -> QueryState -> Vector Value
    executeQuery :: QueryState -> Query -> QueryState -> Vector Value
    curVal :: QueryState -> Value
    rootVal :: QueryState -> Value
    ..} = case QueryType
    queryType of
      QueryType
    Root    -> (Vector Value -> QuerySegment Query -> Vector Value)
    -> Vector Value -> [QuerySegment Query] -> Vector Value
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Vector Value -> QuerySegment Query -> Vector Value
    applySegment (Value -> Vector Value
    forall a. a -> Vector a
    V.singleton Value
    rootVal) [QuerySegment Query]
    querySegments
      QueryType
    Current -> (Vector Value -> QuerySegment Query -> Vector Value)
    -> Vector Value -> [QuerySegment Query] -> Vector Value
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Vector Value -> QuerySegment Query -> Vector Value
    applySegment (Value -> Vector Value
    forall a. a -> Vector a
    V.singleton Value
    curVal) [QuerySegment Query]
    querySegments
      where
        applySegment :: Vector Value -> QuerySegment Query -> Vector Value
        applySegment :: Vector Value -> QuerySegment Query -> Vector Value
    applySegment Vector Value
    vec QuerySegment Query
    seg = Vector (Vector Value) -> Vector Value
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (Vector (Vector Value) -> Vector Value)
    -> Vector (Vector Value) -> Vector Value
    forall a b. (a -> b) -> a -> b
    $ (Value -> Vector Value) -> Vector Value -> Vector (Vector Value)
    forall a b. (a -> b) -> Vector a -> Vector b
    V.map (\Value
    x -> QuerySegment Query -> QueryState -> Vector Value
    qQuerySegment QuerySegment Query
    seg QueryState
    qS{ curVal = x }) Vector Value
    vec

    -- | Runs the JSONPath Query also returning node locations
    qQueryLocated :: Query -> QueryState -> String -> Vector (String,Value)
    qQueryLocated :: Query -> QueryState -> String -> Vector (String, Value)
    qQueryLocated Query{[QuerySegment Query]
    QueryType
    querySegments :: Query -> [QuerySegment Query]
    queryType :: Query -> QueryType
    queryType :: QueryType
    querySegments :: [QuerySegment Query]
    ..} qS :: QueryState
    qS@QueryState{Value
    Query -> QueryState -> Vector Value
    executeQuery :: QueryState -> Query -> QueryState -> Vector Value
    curVal :: QueryState -> Value
    rootVal :: QueryState -> Value
    rootVal :: Value
    curVal :: Value
    executeQuery :: Query -> QueryState -> Vector Value
    ..} String
    loc = case QueryType
    queryType of
      QueryType
    Root    -> (Vector (String, Value)
     -> QuerySegment Query -> Vector (String, Value))
    -> Vector (String, Value)
    -> [QuerySegment Query]
    -> Vector (String, Value)
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Vector (String, Value)
    -> QuerySegment Query -> Vector (String, Value)
    applySegment ((String, Value) -> Vector (String, Value)
    forall a. a -> Vector a
    V.singleton (String
    loc,Value
    rootVal)) [QuerySegment Query]
    querySegments
      QueryType
    Current -> (Vector (String, Value)
     -> QuerySegment Query -> Vector (String, Value))
    -> Vector (String, Value)
    -> [QuerySegment Query]
    -> Vector (String, Value)
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl Vector (String, Value)
    -> QuerySegment Query -> Vector (String, Value)
    applySegment ((String, Value) -> Vector (String, Value)
    forall a. a -> Vector a
    V.singleton (String
    loc,Value
    curVal)) [QuerySegment Query]
    querySegments
      where
        applySegment :: Vector (String,Value) -> QuerySegment Query -> Vector (String,Value)
        applySegment :: Vector (String, Value)
    -> QuerySegment Query -> Vector (String, Value)
    applySegment Vector (String, Value)
    vec QuerySegment Query
    seg = Vector (Vector (String, Value)) -> Vector (String, Value)
    forall (m :: * -> *) a. Monad m => m (m a) -> m a
    join (Vector (Vector (String, Value)) -> Vector (String, Value))
    -> Vector (Vector (String, Value)) -> Vector (String, Value)
    forall a b. (a -> b) -> a -> b
    $ ((String, Value) -> Vector (String, Value))
    -> Vector (String, Value) -> Vector (Vector (String, Value))
    forall a b. (a -> b) -> Vector a -> Vector b
    V.map (\(String
    location,Value
    cur) -> QuerySegment Query
    -> QueryState -> String -> Vector (String, Value)
    qQuerySegmentLocated QuerySegment Query
    seg QueryState
    qS{ curVal = cur } String
    location) Vector (String, Value)
    vec