{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}

module Okapi.HTTP.Request.Query (
    Query (..),
    ArrayStyle (..),
    ParseError (..),
    parser,
    printer,
    raw,
    param,
    param',
    param_,
    flag,
    flag',
    list,
    list',
    GQuery (..),
    queryCodec,
) where

import Data.Bifunctor (first)
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.ByteString.Char8 qualified as BS8
import Data.Int (Int16, Int32, Int64)
import Data.Kind (Type)
import Data.List (partition)
import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified as NE
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Encoding (decodeUtf8Lenient, encodeUtf8)
import Data.Time (Day, UTCTime)
import Data.UUID (UUID)
import GHC.Generics (C1, D1, Generic (..), K1 (..), M1 (..), Rec0, S1, Selector (..), (:*:) (..))
import Network.HTTP.Types qualified as HTTP
import Okapi.Tree (Failure, HasLeaf (..), Info (..), Leaf (..), Parser, Printer, Piece, Context, Tree (..))
import Okapi.Tree qualified as Tree
import Web.HttpApiData (parseQueryParam, toQueryParam)

-- $setup
-- >>> :set -XApplicativeDo
-- >>> import Okapi.Tree (printParse, printStable, int, integer, (=.))
-- >>> import Data.List.NonEmpty (NonEmpty((:|)))
-- >>> :{
-- let twoParams = do
--       x <- fst =. param "x" int
--       y <- snd =. param "y" int
--       pure (x, y)
-- :}

type Query :: Type -> Type
data Query a where
    Raw    :: Query HTTP.Query
    Param  :: Text -> Leaf Query a -> Query a
    Param' :: Text -> Leaf Query a -> Query (Maybe a)
    Param_ :: Text -> Leaf Query a -> a -> Query ()
    Flag   :: Text -> Query ()
    Flag'  :: Text -> Query Bool
    List   :: ArrayStyle -> Text -> Leaf Query a -> Query (NonEmpty a)
    List'  :: ArrayStyle -> Text -> Leaf Query a -> Query [a]

data ArrayStyle = Exploded | CommaDelimited | SpaceDelimited | PipeDelimited deriving (ArrayStyle -> ArrayStyle -> Bool
(ArrayStyle -> ArrayStyle -> Bool)
-> (ArrayStyle -> ArrayStyle -> Bool) -> Eq ArrayStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ArrayStyle -> ArrayStyle -> Bool
== :: ArrayStyle -> ArrayStyle -> Bool
$c/= :: ArrayStyle -> ArrayStyle -> Bool
/= :: ArrayStyle -> ArrayStyle -> Bool
Eq, Int -> ArrayStyle -> ShowS
[ArrayStyle] -> ShowS
ArrayStyle -> String
(Int -> ArrayStyle -> ShowS)
-> (ArrayStyle -> String)
-> ([ArrayStyle] -> ShowS)
-> Show ArrayStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ArrayStyle -> ShowS
showsPrec :: Int -> ArrayStyle -> ShowS
$cshow :: ArrayStyle -> String
show :: ArrayStyle -> String
$cshowList :: [ArrayStyle] -> ShowS
showList :: [ArrayStyle] -> ShowS
Show)

data ParseError = ParseError deriving (ParseError -> ParseError -> Bool
(ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> Bool) -> Eq ParseError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ParseError -> ParseError -> Bool
== :: ParseError -> ParseError -> Bool
$c/= :: ParseError -> ParseError -> Bool
/= :: ParseError -> ParseError -> Bool
Eq, Int -> ParseError -> ShowS
[ParseError] -> ShowS
ParseError -> String
(Int -> ParseError -> ShowS)
-> (ParseError -> String)
-> ([ParseError] -> ShowS)
-> Show ParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParseError -> ShowS
showsPrec :: Int -> ParseError -> ShowS
$cshow :: ParseError -> String
show :: ParseError -> String
$cshowList :: [ParseError] -> ShowS
showList :: [ParseError] -> ShowS
Show)

type instance Context Query = HTTP.Query
type instance Failure Query = ParseError
type instance Piece Query = Text

parser :: Tree Query i o -> Parser Query o
parser :: forall i o. Tree Query i o -> Parser Query o
parser = (forall a. Query a -> Parser Query a)
-> Tree Query i o
-> Context Query
-> (Either (Failure Query) o, Context Query)
forall (t :: * -> *) i o.
(forall a. t a -> Parser t a) -> Tree t i o -> Parser t o
Tree.parser Query a -> Parser Query a
forall a. Query a -> Parser Query a
alg
  where
    alg :: Query a -> Parser Query a
    alg :: forall a. Query a -> Parser Query a
alg Query a
Raw Context Query
q = (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Context Query
q, [])
    alg (Param Text
key Leaf Query a
vLeaf) Context Query
q =
        case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
k, Maybe ByteString
_) -> ByteString
k ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> ByteString
encodeUtf8 Text
key) [QueryItem]
Context Query
q of
            ([], [QueryItem]
_)                 -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
            ((ByteString
_, Maybe ByteString
Nothing) : [QueryItem]
_, [QueryItem]
_)  -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
            ((ByteString
_, Just ByteString
v) : [QueryItem]
_, [QueryItem]
rest) -> case Leaf Query a
vLeaf.decode (ByteString -> Text
decodeUtf8Lenient ByteString
v) of
                Left ParseError
e  -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
e, Context Query
q)
                Right a
x -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
x, [QueryItem]
Context Query
rest)
    alg (Param' Text
key Leaf Query a
vLeaf) Context Query
q =
        case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
k, Maybe ByteString
_) -> ByteString
k ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> ByteString
encodeUtf8 Text
key) [QueryItem]
Context Query
q of
            ([], [QueryItem]
_)                  -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Maybe a
forall a. Maybe a
Nothing, Context Query
q)
            ((ByteString
_, Maybe ByteString
Nothing) : [QueryItem]
_, [QueryItem]
rest) -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Maybe a
forall a. Maybe a
Nothing, [QueryItem]
Context Query
rest)
            ((ByteString
_, Just ByteString
v) : [QueryItem]
_, [QueryItem]
rest)  -> case Leaf Query a
vLeaf.decode (ByteString -> Text
decodeUtf8Lenient ByteString
v) of
                Left ParseError
_  -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Maybe a
forall a. Maybe a
Nothing, [QueryItem]
Context Query
rest)
                Right a
x -> (a -> Either ParseError a
forall a b. b -> Either a b
Right (a -> Maybe a
forall a. a -> Maybe a
Just a
x), [QueryItem]
Context Query
rest)
    alg (Flag Text
key) Context Query
q =
        case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
k, Maybe ByteString
_) -> ByteString
k ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> ByteString
encodeUtf8 Text
key) [QueryItem]
Context Query
q of
            ([], [QueryItem]
_)       -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
            (QueryItem
_ : [QueryItem]
_, [QueryItem]
rest) -> (a -> Either ParseError a
forall a b. b -> Either a b
Right (), [QueryItem]
Context Query
rest)
    alg (Param_ Text
key Leaf Query a
vLeaf a
x) Context Query
q =
        case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
k, Maybe ByteString
_) -> ByteString
k ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> ByteString
encodeUtf8 Text
key) [QueryItem]
Context Query
q of
            ((ByteString
_, Just ByteString
v) : [QueryItem]
_, [QueryItem]
rest) | ByteString -> Text
decodeUtf8Lenient ByteString
v Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Leaf Query a
vLeaf.encode a
x -> (a -> Either ParseError a
forall a b. b -> Either a b
Right (), [QueryItem]
Context Query
rest)
            ([QueryItem], [QueryItem])
_ -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
    alg (Flag' Text
key) Context Query
q =
        case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
k, Maybe ByteString
_) -> ByteString
k ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> ByteString
encodeUtf8 Text
key) [QueryItem]
Context Query
q of
            ([], [QueryItem]
_)       -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Bool
False, Context Query
q)
            (QueryItem
_ : [QueryItem]
_, [QueryItem]
rest) -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
Bool
True, [QueryItem]
Context Query
rest)
    alg (List ArrayStyle
style Text
key Leaf Query a
vLeaf) Context Query
q =
        let ([ByteString]
vals, [QueryItem]
rest) = ArrayStyle -> Text -> [QueryItem] -> ([ByteString], [QueryItem])
collectList ArrayStyle
style Text
key [QueryItem]
Context Query
q
         in case (ByteString -> Either ParseError a)
-> [ByteString] -> Either ParseError [a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Leaf Query a
vLeaf.decode (Text -> Either ParseError a)
-> (ByteString -> Text) -> ByteString -> Either ParseError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decodeUtf8Lenient) [ByteString]
vals of
                Left ParseError
_   -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
                Right [a]
xs -> case [a] -> Maybe (NonEmpty a)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [a]
xs of
                    Maybe (NonEmpty a)
Nothing  -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
                    Just NonEmpty a
nel -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
NonEmpty a
nel, [QueryItem]
Context Query
rest)
    alg (List' ArrayStyle
style Text
key Leaf Query a
vLeaf) Context Query
q =
        let ([ByteString]
vals, [QueryItem]
rest) = ArrayStyle -> Text -> [QueryItem] -> ([ByteString], [QueryItem])
collectList ArrayStyle
style Text
key [QueryItem]
Context Query
q
         in case (ByteString -> Either ParseError a)
-> [ByteString] -> Either ParseError [a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Leaf Query a
vLeaf.decode (Text -> Either ParseError a)
-> (ByteString -> Text) -> ByteString -> Either ParseError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decodeUtf8Lenient) [ByteString]
vals of
                Left ParseError
_   -> (ParseError -> Either ParseError a
forall a b. a -> Either a b
Left ParseError
ParseError, Context Query
q)
                Right [a]
xs -> (a -> Either ParseError a
forall a b. b -> Either a b
Right a
[a]
xs, [QueryItem]
Context Query
rest)

printer :: Tree Query i o -> Printer Query i
printer :: forall i o. Tree Query i o -> Printer Query i
printer = (forall a. Query a -> Printer Query a)
-> Tree Query i o -> i -> Context Query
forall (t :: * -> *) i o.
Monoid (Context t) =>
(forall a. t a -> Printer t a) -> Tree t i o -> Printer t i
Tree.printer Query a -> Printer Query a
forall a. Query a -> Printer Query a
alg
  where
    alg :: Query a -> Printer Query a
    alg :: forall a. Query a -> Printer Query a
alg Query a
Raw                    a
q        = a
Context Query
q
    alg (Param Text
key Leaf Query a
vLeaf)      a
x        = [(Text -> ByteString
encodeUtf8 Text
key, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
encodeUtf8 (Leaf Query a
vLeaf.encode a
x)))]
    alg (Param' Text
_ Leaf Query a
_)           a
Maybe a
Nothing  = []
    alg (Param' Text
key Leaf Query a
vLeaf)     (Just a
x) = [(Text -> ByteString
encodeUtf8 Text
key, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
encodeUtf8 (Leaf Query a
vLeaf.encode a
x)))]
    alg (Param_ Text
key Leaf Query a
vLeaf a
x)   ()       = [(Text -> ByteString
encodeUtf8 Text
key, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
encodeUtf8 (Leaf Query a
vLeaf.encode a
x)))]
    alg (Flag Text
key)             ()       = [(Text -> ByteString
encodeUtf8 Text
key, Maybe ByteString
forall a. Maybe a
Nothing)]
    alg (Flag' Text
key)            a
Bool
True     = [(Text -> ByteString
encodeUtf8 Text
key, Maybe ByteString
forall a. Maybe a
Nothing)]
    alg (Flag' Text
_)              a
Bool
False    = []
    alg (List ArrayStyle
style Text
key Leaf Query a
vLeaf)  a
nel     = ArrayStyle -> Text -> Leaf Query a -> [a] -> [QueryItem]
forall a. ArrayStyle -> Text -> Leaf Query a -> [a] -> [QueryItem]
renderList ArrayStyle
style Text
key Leaf Query a
vLeaf (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList a
NonEmpty a
nel)
    alg (List' ArrayStyle
style Text
key Leaf Query a
vLeaf) a
xs      = ArrayStyle -> Text -> Leaf Query a -> [a] -> [QueryItem]
forall a. ArrayStyle -> Text -> Leaf Query a -> [a] -> [QueryItem]
renderList ArrayStyle
style Text
key Leaf Query a
vLeaf a
[a]
xs

collectList :: ArrayStyle -> Text -> HTTP.Query -> ([ByteString], HTTP.Query)
collectList :: ArrayStyle -> Text -> [QueryItem] -> ([ByteString], [QueryItem])
collectList ArrayStyle
Exploded Text
key [QueryItem]
q =
    let k :: ByteString
k = Text -> ByteString
encodeUtf8 Text
key
        ([QueryItem]
matched, [QueryItem]
rest) = (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
ik, Maybe ByteString
_) -> ByteString
ik ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
k) [QueryItem]
q
     in ([ByteString
v | (ByteString
_, Just ByteString
v) <- [QueryItem]
matched], [QueryItem]
rest)
collectList ArrayStyle
style Text
key [QueryItem]
q =
    let k :: ByteString
k = Text -> ByteString
encodeUtf8 Text
key
     in case (QueryItem -> Bool) -> [QueryItem] -> ([QueryItem], [QueryItem])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (\(ByteString
ik, Maybe ByteString
_) -> ByteString
ik ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
k) [QueryItem]
q of
            ([], [QueryItem]
_) -> ([], [QueryItem]
q)
            ((ByteString
_, Maybe ByteString
Nothing) : [QueryItem]
_, [QueryItem]
rest) -> ([], [QueryItem]
rest)
            ((ByteString
_, Just ByteString
v) : [QueryItem]
_, [QueryItem]
rest) -> ((ByteString -> Bool) -> [ByteString] -> [ByteString]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (ByteString -> Bool) -> ByteString -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Bool
BS.null) (Char -> ByteString -> [ByteString]
BS8.split (ArrayStyle -> Char
delim ArrayStyle
style) ByteString
v), [QueryItem]
rest)

renderList :: ArrayStyle -> Text -> Leaf Query a -> [a] -> HTTP.Query
renderList :: forall a. ArrayStyle -> Text -> Leaf Query a -> [a] -> [QueryItem]
renderList ArrayStyle
Exploded Text
key Leaf Query a
vLeaf [a]
xs = [(Text -> ByteString
encodeUtf8 Text
key, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (a -> ByteString
enc a
x)) | a
x <- [a]
xs]
  where
    enc :: a -> ByteString
enc = Text -> ByteString
encodeUtf8 (Text -> ByteString) -> (a -> Text) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Leaf Query a
vLeaf.encode
renderList ArrayStyle
style Text
key Leaf Query a
vLeaf [a]
xs
    | [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
xs   = []
    | Bool
otherwise = [(Text -> ByteString
encodeUtf8 Text
key, ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> [ByteString] -> ByteString
BS.intercalate (Char -> ByteString
BS8.singleton (ArrayStyle -> Char
delim ArrayStyle
style)) ((a -> ByteString) -> [a] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map a -> ByteString
enc [a]
xs)))]
  where
    enc :: a -> ByteString
enc = Text -> ByteString
encodeUtf8 (Text -> ByteString) -> (a -> Text) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Leaf Query a
vLeaf.encode

delim :: ArrayStyle -> Char
delim :: ArrayStyle -> Char
delim ArrayStyle
CommaDelimited = Char
','
delim ArrayStyle
SpaceDelimited = Char
' '
delim ArrayStyle
PipeDelimited  = Char
'|'
delim ArrayStyle
Exploded       = Char
','

raw :: Tree Query HTTP.Query HTTP.Query
raw :: Tree Query [QueryItem] [QueryItem]
raw = Query [QueryItem] -> Tree Query [QueryItem] [QueryItem]
forall (t :: * -> *) i. t i -> Tree t i i
Node Query [QueryItem]
Raw

-- | Parse and print a required query parameter.
--
-- prop> printParse parser printer (param "k" int) (x :: Int)
-- prop> printStable parser printer (param "k" int) (x :: Int)
param :: Text -> Leaf Query a -> Tree Query a a
param :: forall a. Text -> Leaf Query a -> Tree Query a a
param Text
key Leaf Query a
vLeaf = Query a -> Tree Query a a
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Leaf Query a -> Query a
forall a. Text -> Leaf Query a -> Query a
Param Text
key Leaf Query a
vLeaf)

-- | Parse and print an optional query parameter.
--
-- prop> printParse parser printer (param' "k" int) (x :: Maybe Int)
-- prop> printStable parser printer (param' "k" int) (x :: Maybe Int)
param' :: Text -> Leaf Query a -> Tree Query (Maybe a) (Maybe a)
param' :: forall a. Text -> Leaf Query a -> Tree Query (Maybe a) (Maybe a)
param' Text
key Leaf Query a
vLeaf = Query (Maybe a) -> Tree Query (Maybe a) (Maybe a)
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Leaf Query a -> Query (Maybe a)
forall a. Text -> Leaf Query a -> Query (Maybe a)
Param' Text
key Leaf Query a
vLeaf)

param_ :: Text -> Leaf Query a -> a -> Tree Query () ()
param_ :: forall a. Text -> Leaf Query a -> a -> Tree Query () ()
param_ Text
key Leaf Query a
vLeaf a
x = Query () -> Tree Query () ()
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Leaf Query a -> a -> Query ()
forall a. Text -> Leaf Query a -> a -> Query ()
Param_ Text
key Leaf Query a
vLeaf a
x)

-- | Parse and print a boolean flag (presence = True).
--
-- prop> printParse parser printer (flag "f") ()
-- prop> printParse parser printer (flag' "f") (x :: Bool)
-- prop> printStable parser printer (flag' "f") (x :: Bool)
flag :: Text -> Tree Query () ()
flag :: Text -> Tree Query () ()
flag Text
key = Query () -> Tree Query () ()
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Query ()
Flag Text
key)

flag' :: Text -> Tree Query Bool Bool
flag' :: Text -> Tree Query Bool Bool
flag' Text
key = Query Bool -> Tree Query Bool Bool
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Query Bool
Flag' Text
key)

-- | Parse and print a non-empty list of query parameters.
--
-- prop> printParse parser printer (list Exploded "k" int) (x :| xs)
-- prop> printParse parser printer (list CommaDelimited "k" int) (x :| xs)
-- prop> printStable parser printer (list Exploded "k" int) (x :| xs)
list :: ArrayStyle -> Text -> Leaf Query a -> Tree Query (NonEmpty a) (NonEmpty a)
list :: forall a.
ArrayStyle
-> Text -> Leaf Query a -> Tree Query (NonEmpty a) (NonEmpty a)
list ArrayStyle
style Text
key Leaf Query a
vLeaf = Query (NonEmpty a) -> Tree Query (NonEmpty a) (NonEmpty a)
forall (t :: * -> *) i. t i -> Tree t i i
Node (ArrayStyle -> Text -> Leaf Query a -> Query (NonEmpty a)
forall a. ArrayStyle -> Text -> Leaf Query a -> Query (NonEmpty a)
List ArrayStyle
style Text
key Leaf Query a
vLeaf)

list' :: ArrayStyle -> Text -> Leaf Query a -> Tree Query [a] [a]
list' :: forall a. ArrayStyle -> Text -> Leaf Query a -> Tree Query [a] [a]
list' ArrayStyle
style Text
key Leaf Query a
vLeaf = Query [a] -> Tree Query [a] [a]
forall (t :: * -> *) i. t i -> Tree t i i
Node (ArrayStyle -> Text -> Leaf Query a -> Query [a]
forall a. ArrayStyle -> Text -> Leaf Query a -> Query [a]
List' ArrayStyle
style Text
key Leaf Query a
vLeaf)

instance HasLeaf Query Int        where leaf :: Leaf Query Int
leaf = (Piece Query -> Either (Failure Query) Int)
-> (Int -> Piece Query) -> Info -> Leaf Query Int
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError) -> Either Text Int -> Either ParseError Int
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Int -> Either ParseError Int)
-> (Text -> Either Text Int) -> Text -> Either ParseError Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Int -> Text
Int -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"integer" Maybe Text
forall a. Maybe a
Nothing)
instance HasLeaf Query Int16      where leaf :: Leaf Query Int16
leaf = (Piece Query -> Either (Failure Query) Int16)
-> (Int16 -> Piece Query) -> Info -> Leaf Query Int16
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Int16 -> Either ParseError Int16
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Int16 -> Either ParseError Int16)
-> (Text -> Either Text Int16) -> Text -> Either ParseError Int16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int16
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Int16 -> Text
Int16 -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"integer" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int32"))
instance HasLeaf Query Int32      where leaf :: Leaf Query Int32
leaf = (Piece Query -> Either (Failure Query) Int32)
-> (Int32 -> Piece Query) -> Info -> Leaf Query Int32
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Int32 -> Either ParseError Int32
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Int32 -> Either ParseError Int32)
-> (Text -> Either Text Int32) -> Text -> Either ParseError Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int32
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Int32 -> Text
Int32 -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"integer" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int32"))
instance HasLeaf Query Int64      where leaf :: Leaf Query Int64
leaf = (Piece Query -> Either (Failure Query) Int64)
-> (Int64 -> Piece Query) -> Info -> Leaf Query Int64
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Int64 -> Either ParseError Int64
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Int64 -> Either ParseError Int64)
-> (Text -> Either Text Int64) -> Text -> Either ParseError Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int64
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Int64 -> Text
Int64 -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"integer" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"int64"))
instance HasLeaf Query Integer    where leaf :: Leaf Query Integer
leaf = (Piece Query -> Either (Failure Query) Integer)
-> (Integer -> Piece Query) -> Info -> Leaf Query Integer
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Integer -> Either ParseError Integer
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Integer -> Either ParseError Integer)
-> (Text -> Either Text Integer)
-> Text
-> Either ParseError Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Integer
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Integer -> Text
Integer -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"integer" Maybe Text
forall a. Maybe a
Nothing)
instance HasLeaf Query Bool       where leaf :: Leaf Query Bool
leaf = (Piece Query -> Either (Failure Query) Bool)
-> (Bool -> Piece Query) -> Info -> Leaf Query Bool
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError) -> Either Text Bool -> Either ParseError Bool
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Bool -> Either ParseError Bool)
-> (Text -> Either Text Bool) -> Text -> Either ParseError Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Bool
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Bool -> Text
Bool -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"boolean" Maybe Text
forall a. Maybe a
Nothing)
instance HasLeaf Query Float      where leaf :: Leaf Query Float
leaf = (Piece Query -> Either (Failure Query) Float)
-> (Float -> Piece Query) -> Info -> Leaf Query Float
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Float -> Either ParseError Float
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Float -> Either ParseError Float)
-> (Text -> Either Text Float) -> Text -> Either ParseError Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Float
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Float -> Text
Float -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"number" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"float"))
instance HasLeaf Query Double     where leaf :: Leaf Query Double
leaf = (Piece Query -> Either (Failure Query) Double)
-> (Double -> Piece Query) -> Info -> Leaf Query Double
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text Double -> Either ParseError Double
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Double -> Either ParseError Double)
-> (Text -> Either Text Double) -> Text -> Either ParseError Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Double
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Double -> Text
Double -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"number" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"double"))
instance HasLeaf Query Text       where leaf :: Leaf Query Text
leaf = (Piece Query -> Either (Failure Query) Text)
-> (Text -> Piece Query) -> Info -> Leaf Query Text
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError) -> Either Text Text -> Either ParseError Text
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Text -> Either ParseError Text)
-> (Text -> Either Text Text) -> Text -> Either ParseError Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Text
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Text -> Text
Text -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"string" Maybe Text
forall a. Maybe a
Nothing)
instance HasLeaf Query UUID       where leaf :: Leaf Query UUID
leaf = (Piece Query -> Either (Failure Query) UUID)
-> (UUID -> Piece Query) -> Info -> Leaf Query UUID
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError) -> Either Text UUID -> Either ParseError UUID
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text UUID -> Either ParseError UUID)
-> (Text -> Either Text UUID) -> Text -> Either ParseError UUID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text UUID
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) UUID -> Text
UUID -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"string" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"uuid"))
instance HasLeaf Query Day        where leaf :: Leaf Query Day
leaf = (Piece Query -> Either (Failure Query) Day)
-> (Day -> Piece Query) -> Info -> Leaf Query Day
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError) -> Either Text Day -> Either ParseError Day
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text Day -> Either ParseError Day)
-> (Text -> Either Text Day) -> Text -> Either ParseError Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Day
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) Day -> Text
Day -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"string" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"date"))
instance HasLeaf Query UTCTime    where leaf :: Leaf Query UTCTime
leaf = (Piece Query -> Either (Failure Query) UTCTime)
-> (UTCTime -> Piece Query) -> Info -> Leaf Query UTCTime
forall (t :: * -> *) a.
(Piece t -> Either (Failure t) a)
-> (a -> Piece t) -> Info -> Leaf t a
Leaf ((Text -> ParseError)
-> Either Text UTCTime -> Either ParseError UTCTime
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (ParseError -> Text -> ParseError
forall a b. a -> b -> a
const ParseError
ParseError) (Either Text UTCTime -> Either ParseError UTCTime)
-> (Text -> Either Text UTCTime)
-> Text
-> Either ParseError UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text UTCTime
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam) UTCTime -> Text
UTCTime -> Piece Query
forall a. ToHttpApiData a => a -> Text
toQueryParam (Text -> Maybe Text -> Info
Info Text
"string" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"date-time"))

class GQuery (f :: Type -> Type) where
    gQueryCodec :: Tree Query (f ()) (f ())

instance (GQuery f) => GQuery (D1 meta f) where
    gQueryCodec :: Tree Query (D1 meta f ()) (D1 meta f ())
gQueryCodec = (f () -> D1 meta f ())
-> Tree Query (D1 meta f ()) (f ())
-> Tree Query (D1 meta f ()) (D1 meta f ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap f () -> D1 meta f ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Tree Query (D1 meta f ()) (f ())
 -> Tree Query (D1 meta f ()) (D1 meta f ()))
-> Tree Query (D1 meta f ()) (f ())
-> Tree Query (D1 meta f ()) (D1 meta f ())
forall a b. (a -> b) -> a -> b
$ (D1 meta f () -> f ())
-> Tree Query (f ()) (f ()) -> Tree Query (D1 meta f ()) (f ())
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap D1 meta f () -> f ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1 Tree Query (f ()) (f ())
forall (f :: * -> *). GQuery f => Tree Query (f ()) (f ())
gQueryCodec

instance (GQuery f) => GQuery (C1 meta f) where
    gQueryCodec :: Tree Query (C1 meta f ()) (C1 meta f ())
gQueryCodec = (f () -> C1 meta f ())
-> Tree Query (C1 meta f ()) (f ())
-> Tree Query (C1 meta f ()) (C1 meta f ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap f () -> C1 meta f ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Tree Query (C1 meta f ()) (f ())
 -> Tree Query (C1 meta f ()) (C1 meta f ()))
-> Tree Query (C1 meta f ()) (f ())
-> Tree Query (C1 meta f ()) (C1 meta f ())
forall a b. (a -> b) -> a -> b
$ (C1 meta f () -> f ())
-> Tree Query (f ()) (f ()) -> Tree Query (C1 meta f ()) (f ())
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap C1 meta f () -> f ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1 Tree Query (f ()) (f ())
forall (f :: * -> *). GQuery f => Tree Query (f ()) (f ())
gQueryCodec

instance (GQuery f, GQuery g) => GQuery (f :*: g) where
    gQueryCodec :: Tree Query ((:*:) f g ()) ((:*:) f g ())
gQueryCodec =
        Tree Query ((:*:) f g ()) (g () -> (:*:) f g ())
-> Tree Query ((:*:) f g ()) (g ())
-> Tree Query ((:*:) f g ()) ((:*:) f g ())
forall (t :: * -> *) i o1 o.
Tree t i (o1 -> o) -> Tree t i o1 -> Tree t i o
Apply
            ((f () -> g () -> (:*:) f g ())
-> Tree Query ((:*:) f g ()) (f ())
-> Tree Query ((:*:) f g ()) (g () -> (:*:) f g ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (\f ()
l g ()
r -> f ()
l f () -> g () -> (:*:) f g ()
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g ()
r) (((:*:) f g () -> f ())
-> Tree Query (f ()) (f ()) -> Tree Query ((:*:) f g ()) (f ())
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (\(f ()
l :*: g ()
_) -> f ()
l) Tree Query (f ()) (f ())
forall (f :: * -> *). GQuery f => Tree Query (f ()) (f ())
gQueryCodec))
            (((:*:) f g () -> g ())
-> Tree Query (g ()) (g ()) -> Tree Query ((:*:) f g ()) (g ())
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (\(f ()
_ :*: g ()
r) -> g ()
r) Tree Query (g ()) (g ())
forall (f :: * -> *). GQuery f => Tree Query (f ()) (f ())
gQueryCodec)

instance (Selector s, HasLeaf Query a) => GQuery (S1 s (Rec0 a)) where
    gQueryCodec :: Tree Query (S1 s (Rec0 a) ()) (S1 s (Rec0 a) ())
gQueryCodec =
        let key :: Text
key = String -> Text
Text.pack (S1 s (Rec0 a) () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName (S1 s (Rec0 a) ()
forall a. HasCallStack => a
undefined :: S1 s (Rec0 a) ()))
         in (a -> S1 s (Rec0 a) ())
-> Tree Query (S1 s (Rec0 a) ()) a
-> Tree Query (S1 s (Rec0 a) ()) (S1 s (Rec0 a) ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (Rec0 a () -> S1 s (Rec0 a) ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Rec0 a () -> S1 s (Rec0 a) ())
-> (a -> Rec0 a ()) -> a -> S1 s (Rec0 a) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Rec0 a ()
forall k i c (p :: k). c -> K1 i c p
K1) (Tree Query (S1 s (Rec0 a) ()) a
 -> Tree Query (S1 s (Rec0 a) ()) (S1 s (Rec0 a) ()))
-> Tree Query (S1 s (Rec0 a) ()) a
-> Tree Query (S1 s (Rec0 a) ()) (S1 s (Rec0 a) ())
forall a b. (a -> b) -> a -> b
$ (S1 s (Rec0 a) () -> a)
-> Tree Query a a -> Tree Query (S1 s (Rec0 a) ()) a
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (Rec0 a () -> a
forall k i c (p :: k). K1 i c p -> c
unK1 (Rec0 a () -> a)
-> (S1 s (Rec0 a) () -> Rec0 a ()) -> S1 s (Rec0 a) () -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. S1 s (Rec0 a) () -> Rec0 a ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1) (Tree Query a a -> Tree Query (S1 s (Rec0 a) ()) a)
-> Tree Query a a -> Tree Query (S1 s (Rec0 a) ()) a
forall a b. (a -> b) -> a -> b
$ Query a -> Tree Query a a
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Leaf Query a -> Query a
forall a. Text -> Leaf Query a -> Query a
Param Text
key (forall (t :: * -> *) a. HasLeaf t a => Leaf t a
leaf @Query @a))

instance {-# OVERLAPPING #-} (Selector s, HasLeaf Query a) => GQuery (S1 s (Rec0 (Maybe a))) where
    gQueryCodec :: Tree Query (S1 s (Rec0 (Maybe a)) ()) (S1 s (Rec0 (Maybe a)) ())
gQueryCodec =
        let key :: Text
key = String -> Text
Text.pack (S1 s (Rec0 (Maybe a)) () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName (S1 s (Rec0 (Maybe a)) ()
forall a. HasCallStack => a
undefined :: S1 s (Rec0 (Maybe a)) ()))
         in (Maybe a -> S1 s (Rec0 (Maybe a)) ())
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a)
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (S1 s (Rec0 (Maybe a)) ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (Rec0 (Maybe a) () -> S1 s (Rec0 (Maybe a)) ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Rec0 (Maybe a) () -> S1 s (Rec0 (Maybe a)) ())
-> (Maybe a -> Rec0 (Maybe a) ())
-> Maybe a
-> S1 s (Rec0 (Maybe a)) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> Rec0 (Maybe a) ()
forall k i c (p :: k). c -> K1 i c p
K1) (Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a)
 -> Tree
      Query (S1 s (Rec0 (Maybe a)) ()) (S1 s (Rec0 (Maybe a)) ()))
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a)
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (S1 s (Rec0 (Maybe a)) ())
forall a b. (a -> b) -> a -> b
$ (S1 s (Rec0 (Maybe a)) () -> Maybe a)
-> Tree Query (Maybe a) (Maybe a)
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a)
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (Rec0 (Maybe a) () -> Maybe a
forall k i c (p :: k). K1 i c p -> c
unK1 (Rec0 (Maybe a) () -> Maybe a)
-> (S1 s (Rec0 (Maybe a)) () -> Rec0 (Maybe a) ())
-> S1 s (Rec0 (Maybe a)) ()
-> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. S1 s (Rec0 (Maybe a)) () -> Rec0 (Maybe a) ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1) (Tree Query (Maybe a) (Maybe a)
 -> Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a))
-> Tree Query (Maybe a) (Maybe a)
-> Tree Query (S1 s (Rec0 (Maybe a)) ()) (Maybe a)
forall a b. (a -> b) -> a -> b
$ Query (Maybe a) -> Tree Query (Maybe a) (Maybe a)
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Leaf Query a -> Query (Maybe a)
forall a. Text -> Leaf Query a -> Query (Maybe a)
Param' Text
key (forall (t :: * -> *) a. HasLeaf t a => Leaf t a
leaf @Query @a))

instance {-# OVERLAPPING #-} (Selector s) => GQuery (S1 s (Rec0 ())) where
    gQueryCodec :: Tree Query (S1 s (Rec0 ()) ()) (S1 s (Rec0 ()) ())
gQueryCodec =
        let key :: Text
key = String -> Text
Text.pack (S1 s (Rec0 ()) () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName (S1 s (Rec0 ()) ()
forall a. HasCallStack => a
undefined :: S1 s (Rec0 ()) ()))
         in (() -> S1 s (Rec0 ()) ())
-> Tree Query (S1 s (Rec0 ()) ()) ()
-> Tree Query (S1 s (Rec0 ()) ()) (S1 s (Rec0 ()) ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (Rec0 () () -> S1 s (Rec0 ()) ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Rec0 () () -> S1 s (Rec0 ()) ())
-> (() -> Rec0 () ()) -> () -> S1 s (Rec0 ()) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> Rec0 () ()
forall k i c (p :: k). c -> K1 i c p
K1) (Tree Query (S1 s (Rec0 ()) ()) ()
 -> Tree Query (S1 s (Rec0 ()) ()) (S1 s (Rec0 ()) ()))
-> Tree Query (S1 s (Rec0 ()) ()) ()
-> Tree Query (S1 s (Rec0 ()) ()) (S1 s (Rec0 ()) ())
forall a b. (a -> b) -> a -> b
$ (S1 s (Rec0 ()) () -> ())
-> Tree Query () () -> Tree Query (S1 s (Rec0 ()) ()) ()
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (Rec0 () () -> ()
forall k i c (p :: k). K1 i c p -> c
unK1 (Rec0 () () -> ())
-> (S1 s (Rec0 ()) () -> Rec0 () ()) -> S1 s (Rec0 ()) () -> ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. S1 s (Rec0 ()) () -> Rec0 () ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1) (Tree Query () () -> Tree Query (S1 s (Rec0 ()) ()) ())
-> Tree Query () () -> Tree Query (S1 s (Rec0 ()) ()) ()
forall a b. (a -> b) -> a -> b
$ Query () -> Tree Query () ()
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Query ()
Flag Text
key)

instance {-# OVERLAPPING #-} (Selector s) => GQuery (S1 s (Rec0 Bool)) where
    gQueryCodec :: Tree Query (S1 s (Rec0 Bool) ()) (S1 s (Rec0 Bool) ())
gQueryCodec =
        let key :: Text
key = String -> Text
Text.pack (S1 s (Rec0 Bool) () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName (S1 s (Rec0 Bool) ()
forall a. HasCallStack => a
undefined :: S1 s (Rec0 Bool) ()))
         in (Bool -> S1 s (Rec0 Bool) ())
-> Tree Query (S1 s (Rec0 Bool) ()) Bool
-> Tree Query (S1 s (Rec0 Bool) ()) (S1 s (Rec0 Bool) ())
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (Rec0 Bool () -> S1 s (Rec0 Bool) ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Rec0 Bool () -> S1 s (Rec0 Bool) ())
-> (Bool -> Rec0 Bool ()) -> Bool -> S1 s (Rec0 Bool) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Rec0 Bool ()
forall k i c (p :: k). c -> K1 i c p
K1) (Tree Query (S1 s (Rec0 Bool) ()) Bool
 -> Tree Query (S1 s (Rec0 Bool) ()) (S1 s (Rec0 Bool) ()))
-> Tree Query (S1 s (Rec0 Bool) ()) Bool
-> Tree Query (S1 s (Rec0 Bool) ()) (S1 s (Rec0 Bool) ())
forall a b. (a -> b) -> a -> b
$ (S1 s (Rec0 Bool) () -> Bool)
-> Tree Query Bool Bool -> Tree Query (S1 s (Rec0 Bool) ()) Bool
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (Rec0 Bool () -> Bool
forall k i c (p :: k). K1 i c p -> c
unK1 (Rec0 Bool () -> Bool)
-> (S1 s (Rec0 Bool) () -> Rec0 Bool ())
-> S1 s (Rec0 Bool) ()
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. S1 s (Rec0 Bool) () -> Rec0 Bool ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1) (Tree Query Bool Bool -> Tree Query (S1 s (Rec0 Bool) ()) Bool)
-> Tree Query Bool Bool -> Tree Query (S1 s (Rec0 Bool) ()) Bool
forall a b. (a -> b) -> a -> b
$ Query Bool -> Tree Query Bool Bool
forall (t :: * -> *) i. t i -> Tree t i i
Node (Text -> Query Bool
Flag' Text
key)

queryCodec :: forall a. (Generic a, GQuery (Rep a)) => Tree Query a a
queryCodec :: forall a. (Generic a, GQuery (Rep a)) => Tree Query a a
queryCodec = (Rep a () -> a) -> Tree Query a (Rep a ()) -> Tree Query a a
forall o1 o (t :: * -> *) i. (o1 -> o) -> Tree t i o1 -> Tree t i o
FMap (forall a x. Generic a => Rep a x -> a
to @a) (Tree Query a (Rep a ()) -> Tree Query a a)
-> Tree Query a (Rep a ()) -> Tree Query a a
forall a b. (a -> b) -> a -> b
$ (a -> Rep a ())
-> Tree Query (Rep a ()) (Rep a ()) -> Tree Query a (Rep a ())
forall i i' (t :: * -> *) o. (i -> i') -> Tree t i' o -> Tree t i o
LMap (forall a x. Generic a => a -> Rep a x
from @a) Tree Query (Rep a ()) (Rep a ())
forall (f :: * -> *). GQuery f => Tree Query (f ()) (f ())
gQueryCodec

-- $combined
-- >>> parser twoParams [("x", Just "1"), ("y", Just "2"), ("z", Just "3")]
-- (Right (1,2),[("z",Just "3")])
--
-- prop> printParse parser printer twoParams (xy :: (Int, Int))
-- prop> printStable parser printer twoParams (xy :: (Int, Int))