{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}

-- | Turn your jordan parsers into query-string parsers.
--
-- This module should be considered internal.
-- Import Jordan.Servant.Query instead.
module Jordan.Servant.Query.Parse where

import Control.Applicative (Alternative (..), Applicative (..))
import Control.Monad
import Control.Parallel
import qualified Data.Attoparsec.ByteString as AP
import Data.Bifunctor
import qualified Data.ByteString as BS
import Data.Functor
import Data.Maybe (mapMaybe)
import Data.Monoid
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8', encodeUtf8)
import Debug.Trace
import GHC.Generics
import Jordan (parseViaAttoparsec)
import Jordan.FromJSON.Class
import Jordan.FromJSON.Internal.Permutation
import Jordan.Types.Internal.AccumE
import Jordan.Types.JSONError
import Network.HTTP.Types.URI

data QueryKeyComponent
  = RawValue T.Text
  | EmptyBraces
  | BracedValue T.Text
  deriving (Int -> QueryKeyComponent -> ShowS
[QueryKeyComponent] -> ShowS
QueryKeyComponent -> String
(Int -> QueryKeyComponent -> ShowS)
-> (QueryKeyComponent -> String)
-> ([QueryKeyComponent] -> ShowS)
-> Show QueryKeyComponent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QueryKeyComponent] -> ShowS
$cshowList :: [QueryKeyComponent] -> ShowS
show :: QueryKeyComponent -> String
$cshow :: QueryKeyComponent -> String
showsPrec :: Int -> QueryKeyComponent -> ShowS
$cshowsPrec :: Int -> QueryKeyComponent -> ShowS
Show, ReadPrec [QueryKeyComponent]
ReadPrec QueryKeyComponent
Int -> ReadS QueryKeyComponent
ReadS [QueryKeyComponent]
(Int -> ReadS QueryKeyComponent)
-> ReadS [QueryKeyComponent]
-> ReadPrec QueryKeyComponent
-> ReadPrec [QueryKeyComponent]
-> Read QueryKeyComponent
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [QueryKeyComponent]
$creadListPrec :: ReadPrec [QueryKeyComponent]
readPrec :: ReadPrec QueryKeyComponent
$creadPrec :: ReadPrec QueryKeyComponent
readList :: ReadS [QueryKeyComponent]
$creadList :: ReadS [QueryKeyComponent]
readsPrec :: Int -> ReadS QueryKeyComponent
$creadsPrec :: Int -> ReadS QueryKeyComponent
Read, QueryKeyComponent -> QueryKeyComponent -> Bool
(QueryKeyComponent -> QueryKeyComponent -> Bool)
-> (QueryKeyComponent -> QueryKeyComponent -> Bool)
-> Eq QueryKeyComponent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c/= :: QueryKeyComponent -> QueryKeyComponent -> Bool
== :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c== :: QueryKeyComponent -> QueryKeyComponent -> Bool
Eq, Eq QueryKeyComponent
Eq QueryKeyComponent
-> (QueryKeyComponent -> QueryKeyComponent -> Ordering)
-> (QueryKeyComponent -> QueryKeyComponent -> Bool)
-> (QueryKeyComponent -> QueryKeyComponent -> Bool)
-> (QueryKeyComponent -> QueryKeyComponent -> Bool)
-> (QueryKeyComponent -> QueryKeyComponent -> Bool)
-> (QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent)
-> (QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent)
-> Ord QueryKeyComponent
QueryKeyComponent -> QueryKeyComponent -> Bool
QueryKeyComponent -> QueryKeyComponent -> Ordering
QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent
$cmin :: QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent
max :: QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent
$cmax :: QueryKeyComponent -> QueryKeyComponent -> QueryKeyComponent
>= :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c>= :: QueryKeyComponent -> QueryKeyComponent -> Bool
> :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c> :: QueryKeyComponent -> QueryKeyComponent -> Bool
<= :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c<= :: QueryKeyComponent -> QueryKeyComponent -> Bool
< :: QueryKeyComponent -> QueryKeyComponent -> Bool
$c< :: QueryKeyComponent -> QueryKeyComponent -> Bool
compare :: QueryKeyComponent -> QueryKeyComponent -> Ordering
$ccompare :: QueryKeyComponent -> QueryKeyComponent -> Ordering
$cp1Ord :: Eq QueryKeyComponent
Ord, (forall x. QueryKeyComponent -> Rep QueryKeyComponent x)
-> (forall x. Rep QueryKeyComponent x -> QueryKeyComponent)
-> Generic QueryKeyComponent
forall x. Rep QueryKeyComponent x -> QueryKeyComponent
forall x. QueryKeyComponent -> Rep QueryKeyComponent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep QueryKeyComponent x -> QueryKeyComponent
$cfrom :: forall x. QueryKeyComponent -> Rep QueryKeyComponent x
Generic)

newtype QueryKey = QueryKey {QueryKey -> [QueryKeyComponent]
queryKeyComponents :: [QueryKeyComponent]}
  deriving (Int -> QueryKey -> ShowS
[QueryKey] -> ShowS
QueryKey -> String
(Int -> QueryKey -> ShowS)
-> (QueryKey -> String) -> ([QueryKey] -> ShowS) -> Show QueryKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QueryKey] -> ShowS
$cshowList :: [QueryKey] -> ShowS
show :: QueryKey -> String
$cshow :: QueryKey -> String
showsPrec :: Int -> QueryKey -> ShowS
$cshowsPrec :: Int -> QueryKey -> ShowS
Show, ReadPrec [QueryKey]
ReadPrec QueryKey
Int -> ReadS QueryKey
ReadS [QueryKey]
(Int -> ReadS QueryKey)
-> ReadS [QueryKey]
-> ReadPrec QueryKey
-> ReadPrec [QueryKey]
-> Read QueryKey
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [QueryKey]
$creadListPrec :: ReadPrec [QueryKey]
readPrec :: ReadPrec QueryKey
$creadPrec :: ReadPrec QueryKey
readList :: ReadS [QueryKey]
$creadList :: ReadS [QueryKey]
readsPrec :: Int -> ReadS QueryKey
$creadsPrec :: Int -> ReadS QueryKey
Read, QueryKey -> QueryKey -> Bool
(QueryKey -> QueryKey -> Bool)
-> (QueryKey -> QueryKey -> Bool) -> Eq QueryKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QueryKey -> QueryKey -> Bool
$c/= :: QueryKey -> QueryKey -> Bool
== :: QueryKey -> QueryKey -> Bool
$c== :: QueryKey -> QueryKey -> Bool
Eq, Eq QueryKey
Eq QueryKey
-> (QueryKey -> QueryKey -> Ordering)
-> (QueryKey -> QueryKey -> Bool)
-> (QueryKey -> QueryKey -> Bool)
-> (QueryKey -> QueryKey -> Bool)
-> (QueryKey -> QueryKey -> Bool)
-> (QueryKey -> QueryKey -> QueryKey)
-> (QueryKey -> QueryKey -> QueryKey)
-> Ord QueryKey
QueryKey -> QueryKey -> Bool
QueryKey -> QueryKey -> Ordering
QueryKey -> QueryKey -> QueryKey
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: QueryKey -> QueryKey -> QueryKey
$cmin :: QueryKey -> QueryKey -> QueryKey
max :: QueryKey -> QueryKey -> QueryKey
$cmax :: QueryKey -> QueryKey -> QueryKey
>= :: QueryKey -> QueryKey -> Bool
$c>= :: QueryKey -> QueryKey -> Bool
> :: QueryKey -> QueryKey -> Bool
$c> :: QueryKey -> QueryKey -> Bool
<= :: QueryKey -> QueryKey -> Bool
$c<= :: QueryKey -> QueryKey -> Bool
< :: QueryKey -> QueryKey -> Bool
$c< :: QueryKey -> QueryKey -> Bool
compare :: QueryKey -> QueryKey -> Ordering
$ccompare :: QueryKey -> QueryKey -> Ordering
$cp1Ord :: Eq QueryKey
Ord, (forall x. QueryKey -> Rep QueryKey x)
-> (forall x. Rep QueryKey x -> QueryKey) -> Generic QueryKey
forall x. Rep QueryKey x -> QueryKey
forall x. QueryKey -> Rep QueryKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep QueryKey x -> QueryKey
$cfrom :: forall x. QueryKey -> Rep QueryKey x
Generic)

labelParser :: Parser i a -> String -> Parser i a
labelParser = Parser i a -> String -> Parser i a
forall i a. Parser i a -> String -> Parser i a
(AP.<?>)

escapedBrace :: AP.Parser BS.ByteString
escapedBrace :: Parser ByteString
escapedBrace = do
  ByteString -> Parser ByteString
AP.string ByteString
"]]" Parser ByteString -> String -> Parser ByteString
forall i a. Parser i a -> String -> Parser i a
`labelParser` String
"escaped ending brace"
  (ByteString
"]" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>) (ByteString -> ByteString)
-> Parser ByteString -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
afterBrace

afterBrace :: AP.Parser BS.ByteString
afterBrace :: Parser ByteString
afterBrace = do
  ByteString
taken <- (Word8 -> Bool) -> Parser ByteString
AP.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
93)
  ByteString -> Parser ByteString
AP.string ByteString
"]"
  ByteString -> Parser ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> ByteString -> ByteString
urlDecode Bool
False ByteString
taken)

escapedBraceEnding :: AP.Parser BS.ByteString
escapedBraceEnding :: Parser ByteString
escapedBraceEnding = do
  ByteString
r <- ByteString -> Parser ByteString
AP.string ByteString
"[[" Parser ByteString -> ByteString -> Parser ByteString
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> ByteString
"["
  (ByteString
r ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>) (ByteString -> ByteString)
-> Parser ByteString -> Parser ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString
unbracedValueInner

unbracedValueInner :: AP.Parser BS.ByteString
unbracedValueInner :: Parser ByteString
unbracedValueInner = do
  ByteString
keyChars <- (Word8 -> Bool) -> Parser ByteString
AP.takeWhile (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
91) Parser ByteString -> String -> Parser ByteString
forall i a. Parser i a -> String -> Parser i a
`labelParser` String
"until starting brace"
  ByteString -> Parser ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Parser ByteString)
-> ByteString -> Parser ByteString
forall a b. (a -> b) -> a -> b
$ Bool -> ByteString -> ByteString
urlDecode Bool
False ByteString
keyChars

unbracedValue :: AP.Parser T.Text
unbracedValue :: Parser Text
unbracedValue = do
  ByteString
inner <- Parser ByteString
unbracedValueInner
  case ByteString -> Either UnicodeException Text
decodeUtf8' ByteString
inner of
    Left UnicodeException
err -> String -> Parser Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (UnicodeException -> String
forall a. Show a => a -> String
show UnicodeException
err)
    Right Text
res
      | Text
res Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
forall a. Monoid a => a
mempty -> String -> Parser Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"empty unbraced value, invalid"
      | Bool
otherwise -> Text -> Parser Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
res

bracedValue :: AP.Parser T.Text
bracedValue :: Parser Text
bracedValue = do
  Word8 -> Parser Word8
AP.word8 Word8
91 Parser Word8 -> String -> Parser Word8
forall i a. Parser i a -> String -> Parser i a
`labelParser` String
"starting brace"
  ByteString
after <- Parser ByteString
afterBrace
  case ByteString -> Either UnicodeException Text
decodeUtf8' ByteString
after of
    Left UnicodeException
err -> String -> Parser Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Text) -> String -> Parser Text
forall a b. (a -> b) -> a -> b
$ UnicodeException -> String
forall a. Show a => a -> String
show UnicodeException
err
    Right Text
txt -> Text -> Parser Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
txt

emptyBraces :: Parser ByteString QueryKeyComponent
emptyBraces = do
  ByteString -> Parser ByteString
AP.string ByteString
"[]"
  Maybe Word8
m <- Parser (Maybe Word8)
AP.peekWord8
  case Maybe Word8
m of
    Maybe Word8
Nothing -> QueryKeyComponent -> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a. Applicative f => a -> f a
pure QueryKeyComponent
EmptyBraces
    Just Word8
93 -> String -> Parser ByteString QueryKeyComponent
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"escaped brace"
    Just Word8
_ -> QueryKeyComponent -> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a. Applicative f => a -> f a
pure QueryKeyComponent
EmptyBraces

queryComponent :: AP.Parser QueryKeyComponent
queryComponent :: Parser ByteString QueryKeyComponent
queryComponent =
  Parser ByteString QueryKeyComponent
emptyBraces
    Parser ByteString QueryKeyComponent
-> Parser ByteString QueryKeyComponent
-> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> QueryKeyComponent
RawValue (Text -> QueryKeyComponent)
-> Parser Text -> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
unbracedValue)
    Parser ByteString QueryKeyComponent
-> Parser ByteString QueryKeyComponent
-> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> QueryKeyComponent
BracedValue (Text -> QueryKeyComponent)
-> Parser Text -> Parser ByteString QueryKeyComponent
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
bracedValue)

parseQueryKey :: AP.Parser QueryKey
parseQueryKey :: Parser QueryKey
parseQueryKey = [QueryKeyComponent] -> QueryKey
QueryKey ([QueryKeyComponent] -> QueryKey)
-> Parser ByteString [QueryKeyComponent] -> Parser QueryKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString QueryKeyComponent
-> Parser ByteString [QueryKeyComponent]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some Parser ByteString QueryKeyComponent
queryComponent

newtype QueryParser a = QueryParser
  { QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser ::
      (QueryKey -> Maybe QueryKey) ->
      [(QueryKey, Maybe BS.ByteString)] ->
      Either String (a, [(QueryKey, Maybe BS.ByteString)])
  }

deriving instance Functor QueryParser

instance Applicative QueryParser where
  pure :: a -> QueryParser a
pure a
a = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
_ [(QueryKey, Maybe ByteString)]
q -> (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. b -> Either a b
Right (a
a, [(QueryKey, Maybe ByteString)]
q)
  <*> :: QueryParser (a -> b) -> QueryParser a -> QueryParser b
(<*>) = QueryParser (a -> b) -> QueryParser a -> QueryParser b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad QueryParser where
  QueryParser a
cb >>= :: QueryParser a -> (a -> QueryParser b) -> QueryParser b
>>= a -> QueryParser b
transform = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (b, [(QueryKey, Maybe ByteString)]))
-> QueryParser b
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (b, [(QueryKey, Maybe ByteString)]))
 -> QueryParser b)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (b, [(QueryKey, Maybe ByteString)]))
-> QueryParser b
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
read [(QueryKey, Maybe ByteString)]
q ->
    case QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a.
QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser QueryParser a
cb QueryKey -> Maybe QueryKey
read [(QueryKey, Maybe ByteString)]
q of
      Left String
s -> String -> Either String (b, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
s
      Right (a
a, [(QueryKey, Maybe ByteString)]
q') -> QueryParser b
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (b, [(QueryKey, Maybe ByteString)])
forall a.
QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser (a -> QueryParser b
transform a
a) QueryKey -> Maybe QueryKey
read [(QueryKey, Maybe ByteString)]
q'

-- | Alternative tries the left, than the right.
--
-- Both brances will be sparked off and tried in parallel.
instance Alternative QueryParser where
  empty :: QueryParser a
empty = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
_ [(QueryKey, Maybe ByteString)]
_ -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"Alternative.Empty"
  QueryParser a
lhs <|> :: QueryParser a -> QueryParser a -> QueryParser a
<|> QueryParser a
rhs = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
bs [(QueryKey, Maybe ByteString)]
q ->
    let lhsR :: Either String (a, [(QueryKey, Maybe ByteString)])
lhsR = QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a.
QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser QueryParser a
lhs QueryKey -> Maybe QueryKey
bs [(QueryKey, Maybe ByteString)]
q
        rhsR :: Either String (a, [(QueryKey, Maybe ByteString)])
rhsR = QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a.
QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser QueryParser a
rhs QueryKey -> Maybe QueryKey
bs [(QueryKey, Maybe ByteString)]
q
     in Either String (a, [(QueryKey, Maybe ByteString)])
rhsR Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> b -> b
`par` Either String (a, [(QueryKey, Maybe ByteString)])
lhsR Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> b -> b
`pseq` Either String (a, [(QueryKey, Maybe ByteString)])
lhsR Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Either String (a, [(QueryKey, Maybe ByteString)])
rhsR

peekTransformedKeyHead :: QueryParser QueryKey
peekTransformedKeyHead :: QueryParser QueryKey
peekTransformedKeyHead = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (QueryKey, [(QueryKey, Maybe ByteString)]))
-> QueryParser QueryKey
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (QueryKey, [(QueryKey, Maybe ByteString)]))
 -> QueryParser QueryKey)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (QueryKey, [(QueryKey, Maybe ByteString)]))
-> QueryParser QueryKey
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
q ->
  case [(QueryKey, Maybe ByteString)]
q of
    [] -> String -> Either String (QueryKey, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"no query elements to peek"
    r :: [(QueryKey, Maybe ByteString)]
r@((QueryKey
k, Maybe ByteString
_) : [(QueryKey, Maybe ByteString)]
rest) ->
      case QueryKey -> Maybe QueryKey
transform QueryKey
k of
        Maybe QueryKey
Nothing -> String -> Either String (QueryKey, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"could not transform head"
        Just QueryKey
v -> (QueryKey, [(QueryKey, Maybe ByteString)])
-> Either String (QueryKey, [(QueryKey, Maybe ByteString)])
forall a b. b -> Either a b
Right (QueryKey
v, [(QueryKey, Maybe ByteString)]
r)

readBracketKey :: QueryKey -> QueryParser (T.Text, QueryKeyComponent)
readBracketKey :: QueryKey -> QueryParser (Text, QueryKeyComponent)
readBracketKey (QueryKey [QueryKeyComponent]
query) = do
  case [QueryKeyComponent]
query of
    (b :: QueryKeyComponent
b@(BracedValue Text
val) : [QueryKeyComponent]
rest) -> (Text, QueryKeyComponent) -> QueryParser (Text, QueryKeyComponent)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
val, QueryKeyComponent
b)
    (b :: QueryKeyComponent
b@QueryKeyComponent
EmptyBraces : [QueryKeyComponent]
rest) -> (Text, QueryKeyComponent) -> QueryParser (Text, QueryKeyComponent)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
forall a. Monoid a => a
mempty, QueryKeyComponent
b)
    [QueryKeyComponent]
_ -> String -> QueryParser (Text, QueryKeyComponent)
forall a. String -> QueryParser a
failParse String
"no braced value to consume"

modifyTransformed :: (QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed :: (QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed QueryKey -> Maybe QueryKey
tf (QueryParser (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
cb) = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
key ->
  (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
cb (QueryKey -> Maybe QueryKey
transform (QueryKey -> Maybe QueryKey)
-> (QueryKey -> Maybe QueryKey) -> QueryKey -> Maybe QueryKey
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> QueryKey -> Maybe QueryKey
tf) [(QueryKey, Maybe ByteString)]
key

droppingItem :: QueryKeyComponent -> QueryParser a -> QueryParser a
droppingItem :: QueryKeyComponent -> QueryParser a -> QueryParser a
droppingItem QueryKeyComponent
item = (QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
forall a.
(QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed QueryKey -> Maybe QueryKey
modify
  where
    modify :: QueryKey -> Maybe QueryKey
modify (QueryKey (QueryKeyComponent
i : [QueryKeyComponent]
xs))
      | QueryKeyComponent
i QueryKeyComponent -> QueryKeyComponent -> Bool
forall a. Eq a => a -> a -> Bool
== QueryKeyComponent
item = QueryKey -> Maybe QueryKey
forall a. a -> Maybe a
Just ([QueryKeyComponent] -> QueryKey
QueryKey [QueryKeyComponent]
xs)
      | Bool
otherwise = Maybe QueryKey
forall a. Maybe a
Nothing
    modify QueryKey
_ = Maybe QueryKey
forall a. Maybe a
Nothing

droppingFirst :: QueryParser a -> QueryParser a
droppingFirst :: QueryParser a -> QueryParser a
droppingFirst = (QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
forall a.
(QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed QueryKey -> Maybe QueryKey
dropHead
  where
    dropHead :: QueryKey -> Maybe QueryKey
dropHead (QueryKey (QueryKeyComponent
x : [QueryKeyComponent]
xs)) = QueryKey -> Maybe QueryKey
forall a. a -> Maybe a
Just ([QueryKeyComponent] -> QueryKey
QueryKey [QueryKeyComponent]
xs)
    dropHead QueryKey
_ = Maybe QueryKey
forall a. Maybe a
Nothing

asTuple :: QueryParser a -> QueryParser (T.Text, a)
asTuple :: QueryParser a -> QueryParser (Text, a)
asTuple QueryParser a
qp = do
  QueryKey
keyHead <- QueryParser QueryKey
peekTransformedKeyHead
  (Text
parsedText, QueryKeyComponent
item) <- QueryKey -> QueryParser (Text, QueryKeyComponent)
readBracketKey QueryKey
keyHead
  (Text
parsedText,) (a -> (Text, a)) -> QueryParser a -> QueryParser (Text, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryKeyComponent -> QueryParser a -> QueryParser a
forall a. QueryKeyComponent -> QueryParser a -> QueryParser a
droppingItem QueryKeyComponent
item QueryParser a
qp

getTransform :: QueryParser (QueryKey -> Maybe QueryKey)
getTransform :: QueryParser (QueryKey -> Maybe QueryKey)
getTransform = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either
      String
      (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)]))
-> QueryParser (QueryKey -> Maybe QueryKey)
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either
       String
       (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)]))
 -> QueryParser (QueryKey -> Maybe QueryKey))
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either
         String
         (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)]))
-> QueryParser (QueryKey -> Maybe QueryKey)
forall a b. (a -> b) -> a -> b
$ ((QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)])
 -> Either
      String
      (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)]))
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either
     String (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)])
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)])
-> Either
     String (QueryKey -> Maybe QueryKey, [(QueryKey, Maybe ByteString)])
forall a b. b -> Either a b
Right

failParse :: String -> QueryParser a
failParse String
msg = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
_ [(QueryKey, Maybe ByteString)]
_ -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
msg

-- | Take the value at the head, ensuring along the way that the entire query matches.
takeValue :: QueryParser (Maybe BS.ByteString)
takeValue :: QueryParser (Maybe ByteString)
takeValue = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either
      String (Maybe ByteString, [(QueryKey, Maybe ByteString)]))
-> QueryParser (Maybe ByteString)
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either
       String (Maybe ByteString, [(QueryKey, Maybe ByteString)]))
 -> QueryParser (Maybe ByteString))
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either
         String (Maybe ByteString, [(QueryKey, Maybe ByteString)]))
-> QueryParser (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
queries ->
  case [(QueryKey, Maybe ByteString)]
queries of
    [] -> String
-> Either String (Maybe ByteString, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"no values to take"
    ((QueryKey
k, Maybe ByteString
v) : [(QueryKey, Maybe ByteString)]
rest) ->
      case QueryKey -> Maybe QueryKey
transform QueryKey
k of
        Maybe QueryKey
Nothing -> String
-> Either String (Maybe ByteString, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"bad transform"
        Just (QueryKey []) -> (Maybe ByteString, [(QueryKey, Maybe ByteString)])
-> Either String (Maybe ByteString, [(QueryKey, Maybe ByteString)])
forall a b. b -> Either a b
Right (Maybe ByteString
v, [(QueryKey, Maybe ByteString)]
rest)
        Just QueryKey
r -> String
-> Either String (Maybe ByteString, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left (String
 -> Either
      String (Maybe ByteString, [(QueryKey, Maybe ByteString)]))
-> String
-> Either String (Maybe ByteString, [(QueryKey, Maybe ByteString)])
forall a b. (a -> b) -> a -> b
$ String
"more query elements to consume: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> QueryKey -> String
forall a. Show a => a -> String
show QueryKey
r

takeElement :: QueryParser BS.ByteString
takeElement :: QueryParser ByteString
takeElement = do
  Maybe ByteString
r <- QueryParser (Maybe ByteString)
takeValue
  case Maybe ByteString
r of
    Maybe ByteString
Nothing -> String -> QueryParser ByteString
forall a. String -> QueryParser a
failParse String
"No value"
    Just ByteString
bs -> ByteString -> QueryParser ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
bs

takeNull :: QueryParser ()
takeNull :: QueryParser ()
takeNull = do
  Maybe ByteString
r <- QueryParser (Maybe ByteString)
takeValue
  case Maybe ByteString
r of
    Maybe ByteString
Nothing -> () -> QueryParser ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    Just ByteString
x
      | ByteString
x ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
"null" -> () -> QueryParser ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      | Bool
otherwise -> String -> QueryParser ()
forall a. String -> QueryParser a
failParse String
"encountered values where null was expected"

orParseError :: (Show err) => QueryParser (Either err a) -> QueryParser a
orParseError :: QueryParser (Either err a) -> QueryParser a
orParseError (QueryParser (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (Either err a, [(QueryKey, Maybe ByteString)])
cb) = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
query ->
  case (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (Either err a, [(QueryKey, Maybe ByteString)])
cb QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
query of
    Left String
s -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
s
    Right (Either err a
r, [(QueryKey, Maybe ByteString)]
q) -> case Either err a
r of
      Left err
err -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left (String -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. (a -> b) -> a -> b
$ err -> String
forall a. Show a => a -> String
show err
err
      Right a
a -> (a, [(QueryKey, Maybe ByteString)])
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. b -> Either a b
Right (a
a, [(QueryKey, Maybe ByteString)]
q)

{-
manyEnding parser = many_v
  where
    many_v = some_v <|> (endpure []
    some_v = liftA2 (:) parser many_v
    -}

ensureConsumes :: QueryParser a -> QueryParser a
ensureConsumes :: QueryParser a -> QueryParser a
ensureConsumes QueryParser a
a = ((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a.
((QueryKey -> Maybe QueryKey)
 -> [(QueryKey, Maybe ByteString)]
 -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
QueryParser (((QueryKey -> Maybe QueryKey)
  -> [(QueryKey, Maybe ByteString)]
  -> Either String (a, [(QueryKey, Maybe ByteString)]))
 -> QueryParser a)
-> ((QueryKey -> Maybe QueryKey)
    -> [(QueryKey, Maybe ByteString)]
    -> Either String (a, [(QueryKey, Maybe ByteString)]))
-> QueryParser a
forall a b. (a -> b) -> a -> b
$ \QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
q ->
  case QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
forall a.
QueryParser a
-> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
runQueryParser QueryParser a
a QueryKey -> Maybe QueryKey
transform [(QueryKey, Maybe ByteString)]
q of
    Left String
s -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
s
    r :: Either String (a, [(QueryKey, Maybe ByteString)])
r@(Right (a
res, [(QueryKey, Maybe ByteString)]
nq))
      | [(QueryKey, Maybe ByteString)]
nq [(QueryKey, Maybe ByteString)]
-> [(QueryKey, Maybe ByteString)] -> Bool
forall a. Eq a => a -> a -> Bool
== [(QueryKey, Maybe ByteString)]
q -> String -> Either String (a, [(QueryKey, Maybe ByteString)])
forall a b. a -> Either a b
Left String
"did not consume input"
      | Bool
otherwise -> Either String (a, [(QueryKey, Maybe ByteString)])
r

newtype JordanQueryParser a = JordanQueryParser {JordanQueryParser a -> QueryParser a
runJordanQueryParser :: QueryParser a}
  deriving (a -> JordanQueryParser b -> JordanQueryParser a
(a -> b) -> JordanQueryParser a -> JordanQueryParser b
(forall a b.
 (a -> b) -> JordanQueryParser a -> JordanQueryParser b)
-> (forall a b. a -> JordanQueryParser b -> JordanQueryParser a)
-> Functor JordanQueryParser
forall a b. a -> JordanQueryParser b -> JordanQueryParser a
forall a b. (a -> b) -> JordanQueryParser a -> JordanQueryParser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> JordanQueryParser b -> JordanQueryParser a
$c<$ :: forall a b. a -> JordanQueryParser b -> JordanQueryParser a
fmap :: (a -> b) -> JordanQueryParser a -> JordanQueryParser b
$cfmap :: forall a b. (a -> b) -> JordanQueryParser a -> JordanQueryParser b
Functor, Functor JordanQueryParser
a -> JordanQueryParser a
Functor JordanQueryParser
-> (forall a. a -> JordanQueryParser a)
-> (forall a b.
    JordanQueryParser (a -> b)
    -> JordanQueryParser a -> JordanQueryParser b)
-> (forall a b c.
    (a -> b -> c)
    -> JordanQueryParser a
    -> JordanQueryParser b
    -> JordanQueryParser c)
-> (forall a b.
    JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser b)
-> (forall a b.
    JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser a)
-> Applicative JordanQueryParser
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser b
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser a
JordanQueryParser (a -> b)
-> JordanQueryParser a -> JordanQueryParser b
(a -> b -> c)
-> JordanQueryParser a
-> JordanQueryParser b
-> JordanQueryParser c
forall a. a -> JordanQueryParser a
forall a b.
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser a
forall a b.
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser b
forall a b.
JordanQueryParser (a -> b)
-> JordanQueryParser a -> JordanQueryParser b
forall a b c.
(a -> b -> c)
-> JordanQueryParser a
-> JordanQueryParser b
-> JordanQueryParser c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser a
$c<* :: forall a b.
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser a
*> :: JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser b
$c*> :: forall a b.
JordanQueryParser a -> JordanQueryParser b -> JordanQueryParser b
liftA2 :: (a -> b -> c)
-> JordanQueryParser a
-> JordanQueryParser b
-> JordanQueryParser c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> JordanQueryParser a
-> JordanQueryParser b
-> JordanQueryParser c
<*> :: JordanQueryParser (a -> b)
-> JordanQueryParser a -> JordanQueryParser b
$c<*> :: forall a b.
JordanQueryParser (a -> b)
-> JordanQueryParser a -> JordanQueryParser b
pure :: a -> JordanQueryParser a
$cpure :: forall a. a -> JordanQueryParser a
$cp1Applicative :: Functor JordanQueryParser
Applicative) via QueryParser
  deriving (b -> JordanQueryParser a -> JordanQueryParser a
NonEmpty (JordanQueryParser a) -> JordanQueryParser a
JordanQueryParser a -> JordanQueryParser a -> JordanQueryParser a
(JordanQueryParser a -> JordanQueryParser a -> JordanQueryParser a)
-> (NonEmpty (JordanQueryParser a) -> JordanQueryParser a)
-> (forall b.
    Integral b =>
    b -> JordanQueryParser a -> JordanQueryParser a)
-> Semigroup (JordanQueryParser a)
forall b.
Integral b =>
b -> JordanQueryParser a -> JordanQueryParser a
forall a. NonEmpty (JordanQueryParser a) -> JordanQueryParser a
forall a.
JordanQueryParser a -> JordanQueryParser a -> JordanQueryParser a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b.
Integral b =>
b -> JordanQueryParser a -> JordanQueryParser a
stimes :: b -> JordanQueryParser a -> JordanQueryParser a
$cstimes :: forall a b.
Integral b =>
b -> JordanQueryParser a -> JordanQueryParser a
sconcat :: NonEmpty (JordanQueryParser a) -> JordanQueryParser a
$csconcat :: forall a. NonEmpty (JordanQueryParser a) -> JordanQueryParser a
<> :: JordanQueryParser a -> JordanQueryParser a -> JordanQueryParser a
$c<> :: forall a.
JordanQueryParser a -> JordanQueryParser a -> JordanQueryParser a
Semigroup) via (Alt QueryParser a)

newtype JordanQueryObjectParser a = JordanQueryObjectParser {JordanQueryObjectParser a -> Permutation QueryParser a
runJordanQueryObjectParser :: Permutation QueryParser a}
  deriving (a -> JordanQueryObjectParser b -> JordanQueryObjectParser a
(a -> b) -> JordanQueryObjectParser a -> JordanQueryObjectParser b
(forall a b.
 (a -> b) -> JordanQueryObjectParser a -> JordanQueryObjectParser b)
-> (forall a b.
    a -> JordanQueryObjectParser b -> JordanQueryObjectParser a)
-> Functor JordanQueryObjectParser
forall a b.
a -> JordanQueryObjectParser b -> JordanQueryObjectParser a
forall a b.
(a -> b) -> JordanQueryObjectParser a -> JordanQueryObjectParser b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> JordanQueryObjectParser b -> JordanQueryObjectParser a
$c<$ :: forall a b.
a -> JordanQueryObjectParser b -> JordanQueryObjectParser a
fmap :: (a -> b) -> JordanQueryObjectParser a -> JordanQueryObjectParser b
$cfmap :: forall a b.
(a -> b) -> JordanQueryObjectParser a -> JordanQueryObjectParser b
Functor, Functor JordanQueryObjectParser
a -> JordanQueryObjectParser a
Functor JordanQueryObjectParser
-> (forall a. a -> JordanQueryObjectParser a)
-> (forall a b.
    JordanQueryObjectParser (a -> b)
    -> JordanQueryObjectParser a -> JordanQueryObjectParser b)
-> (forall a b c.
    (a -> b -> c)
    -> JordanQueryObjectParser a
    -> JordanQueryObjectParser b
    -> JordanQueryObjectParser c)
-> (forall a b.
    JordanQueryObjectParser a
    -> JordanQueryObjectParser b -> JordanQueryObjectParser b)
-> (forall a b.
    JordanQueryObjectParser a
    -> JordanQueryObjectParser b -> JordanQueryObjectParser a)
-> Applicative JordanQueryObjectParser
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser b
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser a
JordanQueryObjectParser (a -> b)
-> JordanQueryObjectParser a -> JordanQueryObjectParser b
(a -> b -> c)
-> JordanQueryObjectParser a
-> JordanQueryObjectParser b
-> JordanQueryObjectParser c
forall a. a -> JordanQueryObjectParser a
forall a b.
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser a
forall a b.
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser b
forall a b.
JordanQueryObjectParser (a -> b)
-> JordanQueryObjectParser a -> JordanQueryObjectParser b
forall a b c.
(a -> b -> c)
-> JordanQueryObjectParser a
-> JordanQueryObjectParser b
-> JordanQueryObjectParser c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser a
$c<* :: forall a b.
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser a
*> :: JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser b
$c*> :: forall a b.
JordanQueryObjectParser a
-> JordanQueryObjectParser b -> JordanQueryObjectParser b
liftA2 :: (a -> b -> c)
-> JordanQueryObjectParser a
-> JordanQueryObjectParser b
-> JordanQueryObjectParser c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> JordanQueryObjectParser a
-> JordanQueryObjectParser b
-> JordanQueryObjectParser c
<*> :: JordanQueryObjectParser (a -> b)
-> JordanQueryObjectParser a -> JordanQueryObjectParser b
$c<*> :: forall a b.
JordanQueryObjectParser (a -> b)
-> JordanQueryObjectParser a -> JordanQueryObjectParser b
pure :: a -> JordanQueryObjectParser a
$cpure :: forall a. a -> JordanQueryObjectParser a
$cp1Applicative :: Functor JordanQueryObjectParser
Applicative) via (Permutation QueryParser)

addArrayBrackets :: QueryParser q -> QueryParser q
addArrayBrackets :: QueryParser q -> QueryParser q
addArrayBrackets = (QueryKey -> Maybe QueryKey) -> QueryParser q -> QueryParser q
forall a.
(QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed QueryKey -> Maybe QueryKey
cb
  where
    cb :: QueryKey -> Maybe QueryKey
cb (QueryKey (QueryKeyComponent
EmptyBraces : [QueryKeyComponent]
rest)) = QueryKey -> Maybe QueryKey
forall a. a -> Maybe a
Just ([QueryKeyComponent] -> QueryKey
QueryKey [QueryKeyComponent]
rest)
    cb QueryKey
_ = Maybe QueryKey
forall a. Maybe a
Nothing

addJSONKey :: T.Text -> QueryParser q -> QueryParser q
addJSONKey :: Text -> QueryParser q -> QueryParser q
addJSONKey Text
k = (QueryKey -> Maybe QueryKey) -> QueryParser q -> QueryParser q
forall a.
(QueryKey -> Maybe QueryKey) -> QueryParser a -> QueryParser a
modifyTransformed QueryKey -> Maybe QueryKey
cb
  where
    cb :: QueryKey -> Maybe QueryKey
cb (QueryKey (BracedValue Text
val : [QueryKeyComponent]
rest))
      | Text
val Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
k = QueryKey -> Maybe QueryKey
forall a. a -> Maybe a
Just ([QueryKeyComponent] -> QueryKey
QueryKey [QueryKeyComponent]
rest)
      | Bool
otherwise = Maybe QueryKey
forall a. Maybe a
Nothing
    cb QueryKey
_ = Maybe QueryKey
forall a. Maybe a
Nothing

instance JSONObjectParser JordanQueryObjectParser where
  parseFieldWith :: Text
-> (forall (valueParser :: * -> *).
    JSONParser valueParser =>
    valueParser a)
-> JordanQueryObjectParser a
parseFieldWith Text
field = \(JordanQueryParser q) ->
    Permutation QueryParser a -> JordanQueryObjectParser a
forall a. Permutation QueryParser a -> JordanQueryObjectParser a
JordanQueryObjectParser (Permutation QueryParser a -> JordanQueryObjectParser a)
-> Permutation QueryParser a -> JordanQueryObjectParser a
forall a b. (a -> b) -> a -> b
$
      QueryParser a -> Permutation QueryParser a
forall (f :: * -> *) a. Alternative f => f a -> Permutation f a
asPermutation (QueryParser a -> Permutation QueryParser a)
-> QueryParser a -> Permutation QueryParser a
forall a b. (a -> b) -> a -> b
$
        Text -> QueryParser a -> QueryParser a
forall q. Text -> QueryParser q -> QueryParser q
addJSONKey Text
field QueryParser a
q
  parseFieldWithDefault :: Text
-> (forall (valueParser :: * -> *).
    JSONParser valueParser =>
    valueParser a)
-> a
-> JordanQueryObjectParser a
parseFieldWithDefault Text
f = \(JordanQueryParser q) a
def ->
    Permutation QueryParser a -> JordanQueryObjectParser a
forall a. Permutation QueryParser a -> JordanQueryObjectParser a
JordanQueryObjectParser (Permutation QueryParser a -> JordanQueryObjectParser a)
-> Permutation QueryParser a -> JordanQueryObjectParser a
forall a b. (a -> b) -> a -> b
$
      QueryParser a -> a -> Permutation QueryParser a
forall (f :: * -> *) a.
Alternative f =>
f a -> a -> Permutation f a
asPermutationWithDefault
        (Text -> QueryParser a -> QueryParser a
forall q. Text -> QueryParser q -> QueryParser q
addJSONKey Text
f QueryParser a
q)
        a
def

toBool :: BS.ByteString -> Either JSONError Bool
toBool :: ByteString -> Either JSONError Bool
toBool ByteString
"t" = Bool -> Either JSONError Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
toBool ByteString
"true" = Bool -> Either JSONError Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
toBool ByteString
"f" = Bool -> Either JSONError Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
toBool ByteString
"false" = Bool -> Either JSONError Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
toBool ByteString
_ = JSONError -> Either JSONError Bool
forall a b. a -> Either a b
Left JSONError
ErrorInvalidJSON

takeText :: QueryParser T.Text
takeText :: QueryParser Text
takeText =
  QueryParser (Either UnicodeException Text) -> QueryParser Text
forall err a.
Show err =>
QueryParser (Either err a) -> QueryParser a
orParseError (QueryParser (Either UnicodeException Text) -> QueryParser Text)
-> QueryParser (Either UnicodeException Text) -> QueryParser Text
forall a b. (a -> b) -> a -> b
$
    ByteString -> Either UnicodeException Text
decodeUtf8' (ByteString -> Either UnicodeException Text)
-> QueryParser ByteString
-> QueryParser (Either UnicodeException Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryParser ByteString
takeElement

instance JSONTupleParser JordanQueryParser where
  consumeItemWith :: (forall (valueParser :: * -> *).
 JSONParser valueParser =>
 valueParser a)
-> JordanQueryParser a
consumeItemWith = \forall (valueParser :: * -> *).
JSONParser valueParser =>
valueParser a
x -> JordanQueryParser a
forall (valueParser :: * -> *).
JSONParser valueParser =>
valueParser a
x

instance JSONParser JordanQueryParser where
  parseTuple :: (forall (arrayParser :: * -> *).
 JSONTupleParser arrayParser =>
 arrayParser o)
-> JordanQueryParser o
parseTuple (JordanQueryParser p) =
    QueryParser o -> JordanQueryParser o
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser o -> JordanQueryParser o)
-> QueryParser o -> JordanQueryParser o
forall a b. (a -> b) -> a -> b
$
      QueryParser o -> QueryParser o
forall q. QueryParser q -> QueryParser q
addArrayBrackets QueryParser o
p
  parseObject :: (forall (objectParser :: * -> *).
 JSONObjectParser objectParser =>
 objectParser a)
-> JordanQueryParser a
parseObject = \(JordanQueryObjectParser perm) ->
    QueryParser a -> JordanQueryParser a
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser a -> JordanQueryParser a)
-> QueryParser a -> JordanQueryParser a
forall a b. (a -> b) -> a -> b
$
      Permutation QueryParser a -> QueryParser a
forall (f :: * -> *) a. Alternative f => Permutation f a -> f a
asParser Permutation QueryParser a
perm
  parseArrayWith :: (forall (jsonParser :: * -> *).
 JSONParser jsonParser =>
 jsonParser a)
-> JordanQueryParser [a]
parseArrayWith = \(JordanQueryParser parse) ->
    QueryParser [a] -> JordanQueryParser [a]
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser [a] -> JordanQueryParser [a])
-> QueryParser [a] -> JordanQueryParser [a]
forall a b. (a -> b) -> a -> b
$ QueryParser a -> QueryParser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (QueryParser a -> QueryParser [a])
-> QueryParser a -> QueryParser [a]
forall a b. (a -> b) -> a -> b
$ QueryParser a -> QueryParser a
forall q. QueryParser q -> QueryParser q
ensureConsumes (QueryParser a -> QueryParser a
forall q. QueryParser q -> QueryParser q
addArrayBrackets QueryParser a
parse)
  parseNull :: JordanQueryParser ()
parseNull = QueryParser () -> JordanQueryParser ()
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser QueryParser ()
takeNull
  parseText :: JordanQueryParser Text
parseText = QueryParser Text -> JordanQueryParser Text
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser QueryParser Text
takeText
  parseBool :: JordanQueryParser Bool
parseBool =
    QueryParser Bool -> JordanQueryParser Bool
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser Bool -> JordanQueryParser Bool)
-> QueryParser Bool -> JordanQueryParser Bool
forall a b. (a -> b) -> a -> b
$
      QueryParser (Either JSONError Bool) -> QueryParser Bool
forall err a.
Show err =>
QueryParser (Either err a) -> QueryParser a
orParseError (QueryParser (Either JSONError Bool) -> QueryParser Bool)
-> QueryParser (Either JSONError Bool) -> QueryParser Bool
forall a b. (a -> b) -> a -> b
$ ByteString -> Either JSONError Bool
toBool (ByteString -> Either JSONError Bool)
-> QueryParser ByteString -> QueryParser (Either JSONError Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryParser ByteString
takeElement
  parseDictionary :: (forall (jsonParser :: * -> *).
 JSONParser jsonParser =>
 jsonParser a)
-> JordanQueryParser [(Text, a)]
parseDictionary = \(JordanQueryParser parseValue) ->
    QueryParser [(Text, a)] -> JordanQueryParser [(Text, a)]
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser [(Text, a)] -> JordanQueryParser [(Text, a)])
-> QueryParser [(Text, a)] -> JordanQueryParser [(Text, a)]
forall a b. (a -> b) -> a -> b
$ QueryParser (Text, a) -> QueryParser [(Text, a)]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (QueryParser (Text, a) -> QueryParser [(Text, a)])
-> QueryParser (Text, a) -> QueryParser [(Text, a)]
forall a b. (a -> b) -> a -> b
$ QueryParser (Text, a) -> QueryParser (Text, a)
forall q. QueryParser q -> QueryParser q
ensureConsumes (QueryParser a -> QueryParser (Text, a)
forall a. QueryParser a -> QueryParser (Text, a)
asTuple QueryParser a
parseValue)
  validateJSON :: JordanQueryParser (Either Text a) -> JordanQueryParser a
validateJSON (JordanQueryParser QueryParser (Either Text a)
qp) =
    QueryParser a -> JordanQueryParser a
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser a -> JordanQueryParser a)
-> QueryParser a -> JordanQueryParser a
forall a b. (a -> b) -> a -> b
$
      QueryParser (Either Text a) -> QueryParser a
forall err a.
Show err =>
QueryParser (Either err a) -> QueryParser a
orParseError QueryParser (Either Text a)
qp
  parseNumber :: JordanQueryParser Scientific
parseNumber =
    QueryParser Scientific -> JordanQueryParser Scientific
forall a. QueryParser a -> JordanQueryParser a
JordanQueryParser (QueryParser Scientific -> JordanQueryParser Scientific)
-> QueryParser Scientific -> JordanQueryParser Scientific
forall a b. (a -> b) -> a -> b
$
      QueryParser (Either String Scientific) -> QueryParser Scientific
forall err a.
Show err =>
QueryParser (Either err a) -> QueryParser a
orParseError (QueryParser (Either String Scientific) -> QueryParser Scientific)
-> QueryParser (Either String Scientific) -> QueryParser Scientific
forall a b. (a -> b) -> a -> b
$
        ShowS -> Either String Scientific -> Either String Scientific
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (String -> ShowS
forall a b. a -> b -> a
const String
"not a valid number")
          (Either String Scientific -> Either String Scientific)
-> (ByteString -> Either String Scientific)
-> ByteString
-> Either String Scientific
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String Scientific
forall val. FromJSON val => ByteString -> Either String val
parseViaAttoparsec
          (ByteString -> Either String Scientific)
-> QueryParser ByteString -> QueryParser (Either String Scientific)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryParser ByteString
takeElement

parseQueryToKeys :: Query -> [(QueryKey, Maybe BS.ByteString)]
parseQueryToKeys :: Query -> [(QueryKey, Maybe ByteString)]
parseQueryToKeys = ((ByteString, Maybe ByteString)
 -> Maybe (QueryKey, Maybe ByteString))
-> Query -> [(QueryKey, Maybe ByteString)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (ByteString, Maybe ByteString)
-> Maybe (QueryKey, Maybe ByteString)
forall b. (ByteString, b) -> Maybe (QueryKey, b)
transformElement
  where
    transformElement :: (ByteString, b) -> Maybe (QueryKey, b)
transformElement (ByteString
k, b
v) = case Parser QueryKey -> ByteString -> Either String QueryKey
forall a. Parser a -> ByteString -> Either String a
AP.parseOnly Parser QueryKey
parseQueryKey ByteString
k of
      Left String
s -> Maybe (QueryKey, b)
forall a. Maybe a
Nothing
      Right QueryKey
qk -> (QueryKey, b) -> Maybe (QueryKey, b)
forall a. a -> Maybe a
Just (QueryKey
qk, b
v)

filterToStarting :: T.Text -> [(QueryKey, Maybe BS.ByteString)] -> [(QueryKey, Maybe BS.ByteString)]
filterToStarting :: Text
-> [(QueryKey, Maybe ByteString)] -> [(QueryKey, Maybe ByteString)]
filterToStarting Text
key = ((QueryKey, Maybe ByteString)
 -> Maybe (QueryKey, Maybe ByteString))
-> [(QueryKey, Maybe ByteString)] -> [(QueryKey, Maybe ByteString)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (QueryKey, Maybe ByteString) -> Maybe (QueryKey, Maybe ByteString)
forall b. (QueryKey, b) -> Maybe (QueryKey, b)
keepElement
  where
    keepElement :: (QueryKey, b) -> Maybe (QueryKey, b)
keepElement (QueryKey
k, b
v) =
      case QueryKey
k of
        (QueryKey (RawValue Text
r : [QueryKeyComponent]
rest))
          | Text
r Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
key -> (QueryKey, b) -> Maybe (QueryKey, b)
forall a. a -> Maybe a
Just ([QueryKeyComponent] -> QueryKey
QueryKey [QueryKeyComponent]
rest, b
v)
          | Bool
otherwise -> Maybe (QueryKey, b)
forall a. Maybe a
Nothing
        QueryKey
_ -> Maybe (QueryKey, b)
forall a. Maybe a
Nothing

transformToKey :: Text -> Query -> [(QueryKey, Maybe ByteString)]
transformToKey Text
key = Text
-> [(QueryKey, Maybe ByteString)] -> [(QueryKey, Maybe ByteString)]
filterToStarting Text
key ([(QueryKey, Maybe ByteString)] -> [(QueryKey, Maybe ByteString)])
-> (Query -> [(QueryKey, Maybe ByteString)])
-> Query
-> [(QueryKey, Maybe ByteString)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Query -> [(QueryKey, Maybe ByteString)]
parseQueryToKeys

-- | Use Jordan to parse a query at a given \"base\" key.
--
-- We need a base key in case the JSON type is \"just an int\" or something.
parseQueryAtKeyWith ::
  -- | JSON parser to use.
  -- Note the rank-N type.
  (forall jsonParser. (JSONParser jsonParser) => jsonParser a) ->
  -- | Base key to use in the query string.
  T.Text ->
  -- | Query string
  Query ->
  -- | Either a value, or a brief (not super helpful) description of what went wrong.
  Either String a
parseQueryAtKeyWith :: (forall (jsonParser :: * -> *).
 JSONParser jsonParser =>
 jsonParser a)
-> Text -> Query -> Either String a
parseQueryAtKeyWith (JordanQueryParser (QueryParser q)) Text
key Query
queryString = do
  (a, [(QueryKey, Maybe ByteString)]) -> a
forall a b. (a, b) -> a
fst ((a, [(QueryKey, Maybe ByteString)]) -> a)
-> Either String (a, [(QueryKey, Maybe ByteString)])
-> Either String a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QueryKey -> Maybe QueryKey)
-> [(QueryKey, Maybe ByteString)]
-> Either String (a, [(QueryKey, Maybe ByteString)])
q QueryKey -> Maybe QueryKey
forall a. a -> Maybe a
Just (Text -> Query -> [(QueryKey, Maybe ByteString)]
transformToKey Text
key Query
queryString)

-- | Determine if there are any query keys that match this base key.
--
-- >>> hasQueryAtKey "foo" (parseQuery "foo[bar][baz]=true")
-- True
--
-- >>> hasQueryAtKey "foo" (parseQuery "bar[baz]=true&bar[foo]=true&foo=true")
-- True
--
-- >>> hasQueryAtKey "foo" (parseQuery "bar[baz]=true&bar[foo]=true")
-- False
hasQueryAtKey :: T.Text -> Query -> Bool
hasQueryAtKey :: Text -> Query -> Bool
hasQueryAtKey Text
k Query
q = Bool -> Bool
not ([(QueryKey, Maybe ByteString)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([(QueryKey, Maybe ByteString)] -> Bool)
-> [(QueryKey, Maybe ByteString)] -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> Query -> [(QueryKey, Maybe ByteString)]
transformToKey Text
k Query
q)

-- | Like 'parseQueryAtKeyWith', but uses the 'FromJSON' instance, which is what you want 90% of the time.
parseQueryAtKey :: (FromJSON a) => T.Text -> Query -> Either String a
parseQueryAtKey :: Text -> Query -> Either String a
parseQueryAtKey = (forall (jsonParser :: * -> *).
 JSONParser jsonParser =>
 jsonParser a)
-> Text -> Query -> Either String a
forall a.
(forall (jsonParser :: * -> *).
 JSONParser jsonParser =>
 jsonParser a)
-> Text -> Query -> Either String a
parseQueryAtKeyWith forall value (f :: * -> *).
(FromJSON value, JSONParser f) =>
f value
forall (jsonParser :: * -> *).
JSONParser jsonParser =>
jsonParser a
fromJSON