{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
#include "overlapping-compat.h"
module Web.Internal.FormUrlEncoded where
import Prelude ()
import Prelude.Compat
import Control.Applicative (Const(Const))
import Control.Arrow ((***))
import Control.Monad ((<=<))
import Data.ByteString.Builder (shortByteString, toLazyByteString)
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Lazy.Char8 as BSL8
import Data.Coerce (coerce)
import qualified Data.Foldable as F
import Data.Functor.Identity (Identity(Identity))
import Data.Hashable (Hashable)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.Int (Int16, Int32, Int64, Int8)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.List (intersperse, sortBy)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Monoid (All (..), Any (..), Dual (..),
Product (..), Sum (..))
import Data.Ord (comparing)
import Data.Proxy (Proxy (..))
import Data.Semigroup (Semigroup (..))
import qualified Data.Semigroup as Semi
import Data.Tagged (Tagged (..))
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import Data.Text.Encoding.Error (lenientDecode)
import qualified Data.Text.Lazy as Lazy
import Data.Time.Compat (Day, LocalTime, NominalDiffTime,
UTCTime, ZonedTime)
import Data.Time.Calendar.Month.Compat (Month)
import Data.Time.Calendar.Quarter.Compat (Quarter, QuarterOfYear (..))
import Data.Void (Void)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Exts (Constraint, IsList (..))
import GHC.Generics
import GHC.TypeLits
import Network.HTTP.Types.URI (urlDecode, urlEncodeBuilder)
import Numeric.Natural (Natural)
import Web.Internal.HttpApiData
class ToFormKey k where
toFormKey :: k -> Text
instance ToFormKey () where toFormKey :: () -> Text
toFormKey = () -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Char where toFormKey :: Char -> Text
toFormKey = Char -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Bool where toFormKey :: Bool -> Text
toFormKey = Bool -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Ordering where toFormKey :: Ordering -> Text
toFormKey = Ordering -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Double where toFormKey :: Double -> Text
toFormKey = Double -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Float where toFormKey :: Float -> Text
toFormKey = Float -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Int where toFormKey :: Int -> Text
toFormKey = Int -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Int8 where toFormKey :: Int8 -> Text
toFormKey = Int8 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Int16 where toFormKey :: Int16 -> Text
toFormKey = Int16 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Int32 where toFormKey :: Int32 -> Text
toFormKey = Int32 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Int64 where toFormKey :: Int64 -> Text
toFormKey = Int64 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Integer where toFormKey :: Integer -> Text
toFormKey = Integer -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Word where toFormKey :: Word -> Text
toFormKey = Word -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Word8 where toFormKey :: Word8 -> Text
toFormKey = Word8 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Word16 where toFormKey :: Word16 -> Text
toFormKey = Word16 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Word32 where toFormKey :: Word32 -> Text
toFormKey = Word32 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Word64 where toFormKey :: Word64 -> Text
toFormKey = Word64 -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Day where toFormKey :: Day -> Text
toFormKey = Day -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey LocalTime where toFormKey :: LocalTime -> Text
toFormKey = LocalTime -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey ZonedTime where toFormKey :: ZonedTime -> Text
toFormKey = ZonedTime -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey UTCTime where toFormKey :: UTCTime -> Text
toFormKey = UTCTime -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey NominalDiffTime where toFormKey :: NominalDiffTime -> Text
toFormKey = NominalDiffTime -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Quarter where toFormKey :: Quarter -> Text
toFormKey = Quarter -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey QuarterOfYear where toFormKey :: QuarterOfYear -> Text
toFormKey = QuarterOfYear -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Month where toFormKey :: Month -> Text
toFormKey = Month -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey String where toFormKey :: String -> Text
toFormKey = String -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Text where toFormKey :: Text -> Text
toFormKey = Text -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Lazy.Text where toFormKey :: Text -> Text
toFormKey = Text -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey All where toFormKey :: All -> Text
toFormKey = All -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Any where toFormKey :: Any -> Text
toFormKey = Any -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey a => ToFormKey (Dual a) where toFormKey :: Dual a -> Text
toFormKey = (a -> Text) -> Dual a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Sum a) where toFormKey :: Sum a -> Text
toFormKey = (a -> Text) -> Sum a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Product a) where toFormKey :: Product a -> Text
toFormKey = (a -> Text) -> Product a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Semi.Min a) where toFormKey :: Min a -> Text
toFormKey = (a -> Text) -> Min a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Semi.Max a) where toFormKey :: Max a -> Text
toFormKey = (a -> Text) -> Max a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Semi.First a) where toFormKey :: First a -> Text
toFormKey = (a -> Text) -> First a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Semi.Last a) where toFormKey :: Last a -> Text
toFormKey = (a -> Text) -> Last a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Tagged b a) where toFormKey :: Tagged b a -> Text
toFormKey = (a -> Text) -> Tagged b a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Identity a) where toFormKey :: Identity a -> Text
toFormKey = (a -> Text) -> Identity a -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey a => ToFormKey (Const a b) where
toFormKey :: Const a b -> Text
toFormKey = (a -> Text) -> Const a b -> Text
coerce (a -> Text
forall k. ToFormKey k => k -> Text
toFormKey :: a -> Text)
instance ToFormKey Void where toFormKey :: Void -> Text
toFormKey = Void -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
instance ToFormKey Natural where toFormKey :: Natural -> Text
toFormKey = Natural -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam
class FromFormKey k where
parseFormKey :: Text -> Either Text k
instance FromFormKey () where parseFormKey :: Text -> Either Text ()
parseFormKey = Text -> Either Text ()
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Char where parseFormKey :: Text -> Either Text Char
parseFormKey = Text -> Either Text Char
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Bool where parseFormKey :: Text -> Either Text Bool
parseFormKey = Text -> Either Text Bool
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Ordering where parseFormKey :: Text -> Either Text Ordering
parseFormKey = Text -> Either Text Ordering
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Double where parseFormKey :: Text -> Either Text Double
parseFormKey = Text -> Either Text Double
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Float where parseFormKey :: Text -> Either Text Float
parseFormKey = Text -> Either Text Float
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Int where parseFormKey :: Text -> Either Text Int
parseFormKey = Text -> Either Text Int
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Int8 where parseFormKey :: Text -> Either Text Int8
parseFormKey = Text -> Either Text Int8
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Int16 where parseFormKey :: Text -> Either Text Int16
parseFormKey = Text -> Either Text Int16
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Int32 where parseFormKey :: Text -> Either Text Int32
parseFormKey = Text -> Either Text Int32
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Int64 where parseFormKey :: Text -> Either Text Int64
parseFormKey = Text -> Either Text Int64
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Integer where parseFormKey :: Text -> Either Text Integer
parseFormKey = Text -> Either Text Integer
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Word where parseFormKey :: Text -> Either Text Word
parseFormKey = Text -> Either Text Word
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Word8 where parseFormKey :: Text -> Either Text Word8
parseFormKey = Text -> Either Text Word8
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Word16 where parseFormKey :: Text -> Either Text Word16
parseFormKey = Text -> Either Text Word16
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Word32 where parseFormKey :: Text -> Either Text Word32
parseFormKey = Text -> Either Text Word32
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Word64 where parseFormKey :: Text -> Either Text Word64
parseFormKey = Text -> Either Text Word64
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Day where parseFormKey :: Text -> Either Text Day
parseFormKey = Text -> Either Text Day
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey LocalTime where parseFormKey :: Text -> Either Text LocalTime
parseFormKey = Text -> Either Text LocalTime
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey ZonedTime where parseFormKey :: Text -> Either Text ZonedTime
parseFormKey = Text -> Either Text ZonedTime
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey UTCTime where parseFormKey :: Text -> Either Text UTCTime
parseFormKey = Text -> Either Text UTCTime
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey NominalDiffTime where parseFormKey :: Text -> Either Text NominalDiffTime
parseFormKey = Text -> Either Text NominalDiffTime
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Quarter where parseFormKey :: Text -> Either Text Quarter
parseFormKey = Text -> Either Text Quarter
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey QuarterOfYear where parseFormKey :: Text -> Either Text QuarterOfYear
parseFormKey = Text -> Either Text QuarterOfYear
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Month where parseFormKey :: Text -> Either Text Month
parseFormKey = Text -> Either Text Month
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey String where parseFormKey :: Text -> Either Text String
parseFormKey = Text -> Either Text String
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Text where parseFormKey :: Text -> Either Text Text
parseFormKey = Text -> Either Text Text
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Lazy.Text where parseFormKey :: Text -> Either Text Text
parseFormKey = Text -> Either Text Text
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey All where parseFormKey :: Text -> Either Text All
parseFormKey = Text -> Either Text All
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Any where parseFormKey :: Text -> Either Text Any
parseFormKey = Text -> Either Text Any
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey a => FromFormKey (Dual a) where parseFormKey :: Text -> Either Text (Dual a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Dual a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Sum a) where parseFormKey :: Text -> Either Text (Sum a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Sum a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Product a) where parseFormKey :: Text -> Either Text (Product a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Product a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Semi.Min a) where parseFormKey :: Text -> Either Text (Min a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Min a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Semi.Max a) where parseFormKey :: Text -> Either Text (Max a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Max a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Semi.First a) where parseFormKey :: Text -> Either Text (First a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (First a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Semi.Last a) where parseFormKey :: Text -> Either Text (Last a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Last a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Tagged b a) where parseFormKey :: Text -> Either Text (Tagged b a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Tagged b a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Identity a) where parseFormKey :: Text -> Either Text (Identity a)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Identity a)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey a => FromFormKey (Const a b) where
parseFormKey :: Text -> Either Text (Const a b)
parseFormKey = (Text -> Either Text a) -> Text -> Either Text (Const a b)
coerce (Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey :: Text -> Either Text a)
instance FromFormKey Void where parseFormKey :: Text -> Either Text Void
parseFormKey = Text -> Either Text Void
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
instance FromFormKey Natural where parseFormKey :: Text -> Either Text Natural
parseFormKey = Text -> Either Text Natural
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
newtype Form = Form { Form -> HashMap Text [Text]
unForm :: HashMap Text [Text] }
deriving (Form -> Form -> Bool
(Form -> Form -> Bool) -> (Form -> Form -> Bool) -> Eq Form
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Form -> Form -> Bool
$c/= :: Form -> Form -> Bool
== :: Form -> Form -> Bool
$c== :: Form -> Form -> Bool
Eq, ReadPrec [Form]
ReadPrec Form
Int -> ReadS Form
ReadS [Form]
(Int -> ReadS Form)
-> ReadS [Form] -> ReadPrec Form -> ReadPrec [Form] -> Read Form
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Form]
$creadListPrec :: ReadPrec [Form]
readPrec :: ReadPrec Form
$creadPrec :: ReadPrec Form
readList :: ReadS [Form]
$creadList :: ReadS [Form]
readsPrec :: Int -> ReadS Form
$creadsPrec :: Int -> ReadS Form
Read, (forall x. Form -> Rep Form x)
-> (forall x. Rep Form x -> Form) -> Generic Form
forall x. Rep Form x -> Form
forall x. Form -> Rep Form x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Form x -> Form
$cfrom :: forall x. Form -> Rep Form x
Generic, b -> Form -> Form
NonEmpty Form -> Form
Form -> Form -> Form
(Form -> Form -> Form)
-> (NonEmpty Form -> Form)
-> (forall b. Integral b => b -> Form -> Form)
-> Semigroup Form
forall b. Integral b => b -> Form -> Form
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> Form -> Form
$cstimes :: forall b. Integral b => b -> Form -> Form
sconcat :: NonEmpty Form -> Form
$csconcat :: NonEmpty Form -> Form
<> :: Form -> Form -> Form
$c<> :: Form -> Form -> Form
Semigroup, Semigroup Form
Form
Semigroup Form
-> Form
-> (Form -> Form -> Form)
-> ([Form] -> Form)
-> Monoid Form
[Form] -> Form
Form -> Form -> Form
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [Form] -> Form
$cmconcat :: [Form] -> Form
mappend :: Form -> Form -> Form
$cmappend :: Form -> Form -> Form
mempty :: Form
$cmempty :: Form
$cp1Monoid :: Semigroup Form
Monoid)
instance Show Form where
showsPrec :: Int -> Form -> ShowS
showsPrec Int
d Form
form = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"fromList " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Text, Text)] -> ShowS
forall a. Show a => a -> ShowS
shows (Form -> [(Text, Text)]
toListStable Form
form)
instance IsList Form where
type Item Form = (Text, Text)
fromList :: [Item Form] -> Form
fromList = HashMap Text [Text] -> Form
Form (HashMap Text [Text] -> Form)
-> ([(Text, Text)] -> HashMap Text [Text])
-> [(Text, Text)]
-> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> [Text] -> [Text])
-> [(Text, [Text])] -> HashMap Text [Text]
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> [(k, v)] -> HashMap k v
HashMap.fromListWith (([Text] -> [Text] -> [Text]) -> [Text] -> [Text] -> [Text]
forall a b c. (a -> b -> c) -> b -> a -> c
flip [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
(<>)) ([(Text, [Text])] -> HashMap Text [Text])
-> ([(Text, Text)] -> [(Text, [Text])])
-> [(Text, Text)]
-> HashMap Text [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> (Text, [Text]))
-> [(Text, Text)] -> [(Text, [Text])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Text
k, Text
v) -> (Text
k, [Text
v]))
toList :: Form -> [Item Form]
toList = ((Text, [Text]) -> [(Text, Text)])
-> [(Text, [Text])] -> [(Text, Text)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(Text
k, [Text]
vs) -> (Text -> (Text, Text)) -> [Text] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) Text
k) [Text]
vs) ([(Text, [Text])] -> [(Text, Text)])
-> (Form -> [(Text, [Text])]) -> Form -> [(Text, Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Text [Text] -> [(Text, [Text])]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Text [Text] -> [(Text, [Text])])
-> (Form -> HashMap Text [Text]) -> Form -> [(Text, [Text])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> HashMap Text [Text]
unForm
toListStable :: Form -> [(Text, Text)]
toListStable :: Form -> [(Text, Text)]
toListStable = ((Text, Text) -> Text) -> [(Text, Text)] -> [(Text, Text)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Text, Text) -> Text
forall a b. (a, b) -> a
fst ([(Text, Text)] -> [(Text, Text)])
-> (Form -> [(Text, Text)]) -> Form -> [(Text, Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> [(Text, Text)]
forall l. IsList l => l -> [Item l]
toList
class ToForm a where
toForm :: a -> Form
default toForm :: (Generic a, GToForm a (Rep a)) => a -> Form
toForm = FormOptions -> a -> Form
forall a.
(Generic a, GToForm a (Rep a)) =>
FormOptions -> a -> Form
genericToForm FormOptions
defaultFormOptions
instance ToForm Form where toForm :: Form -> Form
toForm = Form -> Form
forall a. a -> a
id
instance (ToFormKey k, ToHttpApiData v) => ToForm [(k, v)] where
toForm :: [(k, v)] -> Form
toForm = [(Text, Text)] -> Form
forall l. IsList l => [Item l] -> l
fromList ([(Text, Text)] -> Form)
-> ([(k, v)] -> [(Text, Text)]) -> [(k, v)] -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, v) -> (Text, Text)) -> [(k, v)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map (k -> Text
forall k. ToFormKey k => k -> Text
toFormKey (k -> Text) -> (v -> Text) -> (k, v) -> (Text, Text)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** v -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam)
instance (ToFormKey k, ToHttpApiData v) => ToForm (Map k [v]) where
toForm :: Map k [v] -> Form
toForm = [(k, [v])] -> Form
forall k v. (ToFormKey k, ToHttpApiData v) => [(k, [v])] -> Form
fromEntriesByKey ([(k, [v])] -> Form)
-> (Map k [v] -> [(k, [v])]) -> Map k [v] -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map k [v] -> [(k, [v])]
forall k a. Map k a -> [(k, a)]
Map.toList
instance (ToFormKey k, ToHttpApiData v) => ToForm (HashMap k [v]) where
toForm :: HashMap k [v] -> Form
toForm = [(k, [v])] -> Form
forall k v. (ToFormKey k, ToHttpApiData v) => [(k, [v])] -> Form
fromEntriesByKey ([(k, [v])] -> Form)
-> (HashMap k [v] -> [(k, [v])]) -> HashMap k [v] -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap k [v] -> [(k, [v])]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList
instance ToHttpApiData v => ToForm (IntMap [v]) where
toForm :: IntMap [v] -> Form
toForm = [(Int, [v])] -> Form
forall k v. (ToFormKey k, ToHttpApiData v) => [(k, [v])] -> Form
fromEntriesByKey ([(Int, [v])] -> Form)
-> (IntMap [v] -> [(Int, [v])]) -> IntMap [v] -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap [v] -> [(Int, [v])]
forall a. IntMap a -> [(Int, a)]
IntMap.toList
fromEntriesByKey :: (ToFormKey k, ToHttpApiData v) => [(k, [v])] -> Form
fromEntriesByKey :: [(k, [v])] -> Form
fromEntriesByKey = HashMap Text [Text] -> Form
Form (HashMap Text [Text] -> Form)
-> ([(k, [v])] -> HashMap Text [Text]) -> [(k, [v])] -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> [Text] -> [Text])
-> [(Text, [Text])] -> HashMap Text [Text]
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> [(k, v)] -> HashMap k v
HashMap.fromListWith [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
(<>) ([(Text, [Text])] -> HashMap Text [Text])
-> ([(k, [v])] -> [(Text, [Text])])
-> [(k, [v])]
-> HashMap Text [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, [v]) -> (Text, [Text])) -> [(k, [v])] -> [(Text, [Text])]
forall a b. (a -> b) -> [a] -> [b]
map (k -> Text
forall k. ToFormKey k => k -> Text
toFormKey (k -> Text) -> ([v] -> [Text]) -> (k, [v]) -> (Text, [Text])
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** (v -> Text) -> [v] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map v -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam)
data Proxy3 a b c = Proxy3
type family NotSupported (cls :: k1) (a :: k2) (reason :: Symbol) :: Constraint where
#if __GLASGOW_HASKELL__ < 800
NotSupported cls a "this type family is actually empty" = ()
#else
NotSupported cls a reason = TypeError
( 'Text "Cannot derive a Generic-based " ':<>: 'ShowType cls ':<>: 'Text " instance for " ':<>: 'ShowType a ':<>: 'Text "." ':$$:
'ShowType a ':<>: 'Text " " ':<>: 'Text reason ':<>: 'Text "," ':$$:
'Text "but Generic-based " ':<>: 'ShowType cls ':<>: 'Text " instances can be derived only for records" ':$$:
'Text "(i.e. product types with named fields)." )
#endif
genericToForm :: forall a. (Generic a, GToForm a (Rep a)) => FormOptions -> a -> Form
genericToForm :: FormOptions -> a -> Form
genericToForm FormOptions
opts = Proxy a -> FormOptions -> Rep a Any -> Form
forall k (t :: k) (f :: * -> *) x.
GToForm t f =>
Proxy t -> FormOptions -> f x -> Form
gToForm (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) FormOptions
opts (Rep a Any -> Form) -> (a -> Rep a Any) -> a -> Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from
class GToForm t (f :: * -> *) where
gToForm :: Proxy t -> FormOptions -> f x -> Form
instance (GToForm t f, GToForm t g) => GToForm t (f :*: g) where
gToForm :: Proxy t -> FormOptions -> (:*:) f g x -> Form
gToForm Proxy t
p FormOptions
opts (f x
a :*: g x
b) = Proxy t -> FormOptions -> f x -> Form
forall k (t :: k) (f :: * -> *) x.
GToForm t f =>
Proxy t -> FormOptions -> f x -> Form
gToForm Proxy t
p FormOptions
opts f x
a Form -> Form -> Form
forall a. Semigroup a => a -> a -> a
<> Proxy t -> FormOptions -> g x -> Form
forall k (t :: k) (f :: * -> *) x.
GToForm t f =>
Proxy t -> FormOptions -> f x -> Form
gToForm Proxy t
p FormOptions
opts g x
b
instance (GToForm t f) => GToForm t (M1 D x f) where
gToForm :: Proxy t -> FormOptions -> M1 D x f x -> Form
gToForm Proxy t
p FormOptions
opts (M1 f x
a) = Proxy t -> FormOptions -> f x -> Form
forall k (t :: k) (f :: * -> *) x.
GToForm t f =>
Proxy t -> FormOptions -> f x -> Form
gToForm Proxy t
p FormOptions
opts f x
a
instance (GToForm t f) => GToForm t (M1 C x f) where
gToForm :: Proxy t -> FormOptions -> M1 C x f x -> Form
gToForm Proxy t
p FormOptions
opts (M1 f x
a) = Proxy t -> FormOptions -> f x -> Form
forall k (t :: k) (f :: * -> *) x.
GToForm t f =>
Proxy t -> FormOptions -> f x -> Form
gToForm Proxy t
p FormOptions
opts f x
a
instance OVERLAPPABLE_ (Selector s, ToHttpApiData c) => GToForm t (M1 S s (K1 i c)) where
gToForm :: Proxy t -> FormOptions -> M1 S s (K1 i c) x -> Form
gToForm Proxy t
_ FormOptions
opts (M1 (K1 c
c)) = [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList [(Text
key, c -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam c
c)]
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance (Selector s, ToHttpApiData c) => GToForm t (M1 S s (K1 i (Maybe c))) where
gToForm :: Proxy t -> FormOptions -> M1 S s (K1 i (Maybe c)) x -> Form
gToForm Proxy t
_ FormOptions
opts (M1 (K1 Maybe c
c)) =
case Maybe c
c of
Maybe c
Nothing -> Form
forall a. Monoid a => a
mempty
Just c
x -> [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList [(Text
key, c -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam c
x)]
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance (Selector s, ToHttpApiData c) => GToForm t (M1 S s (K1 i [c])) where
gToForm :: Proxy t -> FormOptions -> M1 S s (K1 i [c]) x -> Form
gToForm Proxy t
_ FormOptions
opts (M1 (K1 [c]
cs)) = [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList ((c -> (Text, Text)) -> [c] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map (\c
c -> (Text
key, c -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam c
c)) [c]
cs)
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance OVERLAPPING_ (Selector s) => GToForm t (M1 S s (K1 i String)) where
gToForm :: Proxy t -> FormOptions -> M1 S s (K1 i String) x -> Form
gToForm Proxy t
_ FormOptions
opts (M1 (K1 String
c)) = [Item Form] -> Form
forall l. IsList l => [Item l] -> l
fromList [(Text
key, String -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam String
c)]
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance NotSupported ToForm t "is a sum type" => GToForm t (f :+: g) where gToForm :: Proxy t -> FormOptions -> (:+:) f g x -> Form
gToForm = String -> Proxy t -> FormOptions -> (:+:) f g x -> Form
forall a. HasCallStack => String -> a
error String
"impossible"
class FromForm a where
fromForm :: Form -> Either Text a
default fromForm :: (Generic a, GFromForm a (Rep a)) => Form -> Either Text a
fromForm = FormOptions -> Form -> Either Text a
forall a.
(Generic a, GFromForm a (Rep a)) =>
FormOptions -> Form -> Either Text a
genericFromForm FormOptions
defaultFormOptions
instance FromForm Form where fromForm :: Form -> Either Text Form
fromForm = Form -> Either Text Form
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance (FromFormKey k, FromHttpApiData v) => FromForm [(k, v)] where
fromForm :: Form -> Either Text [(k, v)]
fromForm = ([(k, [v])] -> [(k, v)])
-> Either Text [(k, [v])] -> Either Text [(k, v)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((k, [v]) -> [(k, v)]) -> [(k, [v])] -> [(k, v)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(k
k, [v]
vs) -> (v -> (k, v)) -> [v] -> [(k, v)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) k
k) [v]
vs)) (Either Text [(k, [v])] -> Either Text [(k, v)])
-> (Form -> Either Text [(k, [v])]) -> Form -> Either Text [(k, v)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> Either Text [(k, [v])]
forall k v.
(FromFormKey k, FromHttpApiData v) =>
Form -> Either Text [(k, [v])]
toEntriesByKey
instance (Ord k, FromFormKey k, FromHttpApiData v) => FromForm (Map k [v]) where
fromForm :: Form -> Either Text (Map k [v])
fromForm = ([(k, [v])] -> Map k [v])
-> Either Text [(k, [v])] -> Either Text (Map k [v])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([v] -> [v] -> [v]) -> [(k, [v])] -> Map k [v]
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith [v] -> [v] -> [v]
forall a. Semigroup a => a -> a -> a
(<>)) (Either Text [(k, [v])] -> Either Text (Map k [v]))
-> (Form -> Either Text [(k, [v])])
-> Form
-> Either Text (Map k [v])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> Either Text [(k, [v])]
forall k v.
(FromFormKey k, FromHttpApiData v) =>
Form -> Either Text [(k, [v])]
toEntriesByKey
instance (Eq k, Hashable k, FromFormKey k, FromHttpApiData v) => FromForm (HashMap k [v]) where
fromForm :: Form -> Either Text (HashMap k [v])
fromForm = ([(k, [v])] -> HashMap k [v])
-> Either Text [(k, [v])] -> Either Text (HashMap k [v])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([v] -> [v] -> [v]) -> [(k, [v])] -> HashMap k [v]
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> [(k, v)] -> HashMap k v
HashMap.fromListWith [v] -> [v] -> [v]
forall a. Semigroup a => a -> a -> a
(<>)) (Either Text [(k, [v])] -> Either Text (HashMap k [v]))
-> (Form -> Either Text [(k, [v])])
-> Form
-> Either Text (HashMap k [v])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> Either Text [(k, [v])]
forall k v.
(FromFormKey k, FromHttpApiData v) =>
Form -> Either Text [(k, [v])]
toEntriesByKey
instance FromHttpApiData v => FromForm (IntMap [v]) where
fromForm :: Form -> Either Text (IntMap [v])
fromForm = ([(Int, [v])] -> IntMap [v])
-> Either Text [(Int, [v])] -> Either Text (IntMap [v])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([v] -> [v] -> [v]) -> [(Int, [v])] -> IntMap [v]
forall a. (a -> a -> a) -> [(Int, a)] -> IntMap a
IntMap.fromListWith [v] -> [v] -> [v]
forall a. Semigroup a => a -> a -> a
(<>)) (Either Text [(Int, [v])] -> Either Text (IntMap [v]))
-> (Form -> Either Text [(Int, [v])])
-> Form
-> Either Text (IntMap [v])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> Either Text [(Int, [v])]
forall k v.
(FromFormKey k, FromHttpApiData v) =>
Form -> Either Text [(k, [v])]
toEntriesByKey
toEntriesByKey :: (FromFormKey k, FromHttpApiData v) => Form -> Either Text [(k, [v])]
toEntriesByKey :: Form -> Either Text [(k, [v])]
toEntriesByKey = ((Text, [Text]) -> Either Text (k, [v]))
-> [(Text, [Text])] -> Either Text [(k, [v])]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Text, [Text]) -> Either Text (k, [v])
forall a (t :: * -> *) b.
(FromFormKey a, Traversable t, FromHttpApiData b) =>
(Text, t Text) -> Either Text (a, t b)
parseGroup ([(Text, [Text])] -> Either Text [(k, [v])])
-> (Form -> [(Text, [Text])]) -> Form -> Either Text [(k, [v])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Text [Text] -> [(Text, [Text])]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Text [Text] -> [(Text, [Text])])
-> (Form -> HashMap Text [Text]) -> Form -> [(Text, [Text])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> HashMap Text [Text]
unForm
where
parseGroup :: (Text, t Text) -> Either Text (a, t b)
parseGroup (Text
k, t Text
vs) = (,) (a -> t b -> (a, t b))
-> Either Text a -> Either Text (t b -> (a, t b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Either Text a
forall k. FromFormKey k => Text -> Either Text k
parseFormKey Text
k Either Text (t b -> (a, t b))
-> Either Text (t b) -> Either Text (a, t b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Text -> Either Text b) -> t Text -> Either Text (t b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Text -> Either Text b
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam t Text
vs
toEntriesByKeyStable :: (Ord k, FromFormKey k, FromHttpApiData v) => Form -> Either Text [(k, [v])]
toEntriesByKeyStable :: Form -> Either Text [(k, [v])]
toEntriesByKeyStable = ([(k, [v])] -> [(k, [v])])
-> Either Text [(k, [v])] -> Either Text [(k, [v])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((k, [v]) -> k) -> [(k, [v])] -> [(k, [v])]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (k, [v]) -> k
forall a b. (a, b) -> a
fst) (Either Text [(k, [v])] -> Either Text [(k, [v])])
-> (Form -> Either Text [(k, [v])])
-> Form
-> Either Text [(k, [v])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> Either Text [(k, [v])]
forall k v.
(FromFormKey k, FromHttpApiData v) =>
Form -> Either Text [(k, [v])]
toEntriesByKey
genericFromForm :: forall a. (Generic a, GFromForm a (Rep a)) => FormOptions -> Form -> Either Text a
genericFromForm :: FormOptions -> Form -> Either Text a
genericFromForm FormOptions
opts Form
f = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to (Rep a Any -> a) -> Either Text (Rep a Any) -> Either Text a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy a -> FormOptions -> Form -> Either Text (Rep a Any)
forall k (t :: k) (f :: * -> *) x.
GFromForm t f =>
Proxy t -> FormOptions -> Form -> Either Text (f x)
gFromForm (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) FormOptions
opts Form
f
class GFromForm t (f :: * -> *) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (f x)
instance (GFromForm t f, GFromForm t g) => GFromForm t (f :*: g) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text ((:*:) f g x)
gFromForm Proxy t
p FormOptions
opts Form
f = f x -> g x -> (:*:) f g x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:) (f x -> g x -> (:*:) f g x)
-> Either Text (f x) -> Either Text (g x -> (:*:) f g x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy t -> FormOptions -> Form -> Either Text (f x)
forall k (t :: k) (f :: * -> *) x.
GFromForm t f =>
Proxy t -> FormOptions -> Form -> Either Text (f x)
gFromForm Proxy t
p FormOptions
opts Form
f Either Text (g x -> (:*:) f g x)
-> Either Text (g x) -> Either Text ((:*:) f g x)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Proxy t -> FormOptions -> Form -> Either Text (g x)
forall k (t :: k) (f :: * -> *) x.
GFromForm t f =>
Proxy t -> FormOptions -> Form -> Either Text (f x)
gFromForm Proxy t
p FormOptions
opts Form
f
instance GFromForm t f => GFromForm t (M1 D x f) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (M1 D x f x)
gFromForm Proxy t
p FormOptions
opts Form
f = f x -> M1 D x f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f x -> M1 D x f x)
-> Either Text (f x) -> Either Text (M1 D x f x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy t -> FormOptions -> Form -> Either Text (f x)
forall k (t :: k) (f :: * -> *) x.
GFromForm t f =>
Proxy t -> FormOptions -> Form -> Either Text (f x)
gFromForm Proxy t
p FormOptions
opts Form
f
instance GFromForm t f => GFromForm t (M1 C x f) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (M1 C x f x)
gFromForm Proxy t
p FormOptions
opts Form
f = f x -> M1 C x f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f x -> M1 C x f x)
-> Either Text (f x) -> Either Text (M1 C x f x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy t -> FormOptions -> Form -> Either Text (f x)
forall k (t :: k) (f :: * -> *) x.
GFromForm t f =>
Proxy t -> FormOptions -> Form -> Either Text (f x)
gFromForm Proxy t
p FormOptions
opts Form
f
instance OVERLAPPABLE_ (Selector s, FromHttpApiData c) => GFromForm t (M1 S s (K1 i c)) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (M1 S s (K1 i c) x)
gFromForm Proxy t
_ FormOptions
opts Form
form = K1 i c x -> M1 S s (K1 i c) x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 i c x -> M1 S s (K1 i c) x)
-> (c -> K1 i c x) -> c -> M1 S s (K1 i c) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> K1 i c x
forall k i c (p :: k). c -> K1 i c p
K1 (c -> M1 S s (K1 i c) x)
-> Either Text c -> Either Text (M1 S s (K1 i c) x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Form -> Either Text c
forall v. FromHttpApiData v => Text -> Form -> Either Text v
parseUnique Text
key Form
form
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance (Selector s, FromHttpApiData c) => GFromForm t (M1 S s (K1 i (Maybe c))) where
gFromForm :: Proxy t
-> FormOptions -> Form -> Either Text (M1 S s (K1 i (Maybe c)) x)
gFromForm Proxy t
_ FormOptions
opts Form
form = K1 i (Maybe c) x -> M1 S s (K1 i (Maybe c)) x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 i (Maybe c) x -> M1 S s (K1 i (Maybe c)) x)
-> (Maybe c -> K1 i (Maybe c) x)
-> Maybe c
-> M1 S s (K1 i (Maybe c)) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe c -> K1 i (Maybe c) x
forall k i c (p :: k). c -> K1 i c p
K1 (Maybe c -> M1 S s (K1 i (Maybe c)) x)
-> Either Text (Maybe c) -> Either Text (M1 S s (K1 i (Maybe c)) x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Form -> Either Text (Maybe c)
forall v.
FromHttpApiData v =>
Text -> Form -> Either Text (Maybe v)
parseMaybe Text
key Form
form
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance (Selector s, FromHttpApiData c) => GFromForm t (M1 S s (K1 i [c])) where
gFromForm :: Proxy t -> FormOptions -> Form -> Either Text (M1 S s (K1 i [c]) x)
gFromForm Proxy t
_ FormOptions
opts Form
form = K1 i [c] x -> M1 S s (K1 i [c]) x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 i [c] x -> M1 S s (K1 i [c]) x)
-> ([c] -> K1 i [c] x) -> [c] -> M1 S s (K1 i [c]) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [c] -> K1 i [c] x
forall k i c (p :: k). c -> K1 i c p
K1 ([c] -> M1 S s (K1 i [c]) x)
-> Either Text [c] -> Either Text (M1 S s (K1 i [c]) x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Form -> Either Text [c]
forall v. FromHttpApiData v => Text -> Form -> Either Text [v]
parseAll Text
key Form
form
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance OVERLAPPING_ (Selector s) => GFromForm t (M1 S s (K1 i String)) where
gFromForm :: Proxy t
-> FormOptions -> Form -> Either Text (M1 S s (K1 i String) x)
gFromForm Proxy t
_ FormOptions
opts Form
form = K1 i String x -> M1 S s (K1 i String) x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (K1 i String x -> M1 S s (K1 i String) x)
-> (String -> K1 i String x) -> String -> M1 S s (K1 i String) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> K1 i String x
forall k i c (p :: k). c -> K1 i c p
K1 (String -> M1 S s (K1 i String) x)
-> Either Text String -> Either Text (M1 S s (K1 i String) x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Form -> Either Text String
forall v. FromHttpApiData v => Text -> Form -> Either Text v
parseUnique Text
key Form
form
where
key :: Text
key = String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormOptions -> ShowS
fieldLabelModifier FormOptions
opts ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Proxy3 s Any Any -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall k k (g :: k) (p :: k). Proxy3 s g p
forall k k k (a :: k) (b :: k) (c :: k). Proxy3 a b c
Proxy3 :: Proxy3 s g p)
instance NotSupported FromForm t "is a sum type" => GFromForm t (f :+: g) where gFromForm :: Proxy t -> FormOptions -> Form -> Either Text ((:+:) f g x)
gFromForm = String
-> Proxy t -> FormOptions -> Form -> Either Text ((:+:) f g x)
forall a. HasCallStack => String -> a
error String
"impossible"
urlEncodeForm :: Form -> BSL.ByteString
urlEncodeForm :: Form -> ByteString
urlEncodeForm = [(Text, Text)] -> ByteString
urlEncodeParams ([(Text, Text)] -> ByteString)
-> (Form -> [(Text, Text)]) -> Form -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> [(Text, Text)]
forall l. IsList l => l -> [Item l]
toList
urlEncodeFormStable :: Form -> BSL.ByteString
urlEncodeFormStable :: Form -> ByteString
urlEncodeFormStable = [(Text, Text)] -> ByteString
urlEncodeParams ([(Text, Text)] -> ByteString)
-> (Form -> [(Text, Text)]) -> Form -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> Text) -> [(Text, Text)] -> [(Text, Text)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (Text, Text) -> Text
forall a b. (a, b) -> a
fst ([(Text, Text)] -> [(Text, Text)])
-> (Form -> [(Text, Text)]) -> Form -> [(Text, Text)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> [(Text, Text)]
forall l. IsList l => l -> [Item l]
toList
urlEncodeParams :: [(Text, Text)] -> BSL.ByteString
urlEncodeParams :: [(Text, Text)] -> ByteString
urlEncodeParams = Builder -> ByteString
toLazyByteString (Builder -> ByteString)
-> ([(Text, Text)] -> Builder) -> [(Text, Text)] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([(Text, Text)] -> [Builder]) -> [(Text, Text)] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse (ShortByteString -> Builder
shortByteString ShortByteString
"&") ([Builder] -> [Builder])
-> ([(Text, Text)] -> [Builder]) -> [(Text, Text)] -> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> Builder) -> [(Text, Text)] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Builder
encodePair
where
escape :: Text -> Builder
escape = Bool -> ByteString -> Builder
urlEncodeBuilder Bool
True (ByteString -> Builder) -> (Text -> ByteString) -> Text -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
Text.encodeUtf8
encodePair :: (Text, Text) -> Builder
encodePair (Text
k, Text
"") = Text -> Builder
escape Text
k
encodePair (Text
k, Text
v) = Text -> Builder
escape Text
k Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> Builder
shortByteString ShortByteString
"=" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
escape Text
v
urlDecodeForm :: BSL.ByteString -> Either Text Form
urlDecodeForm :: ByteString -> Either Text Form
urlDecodeForm = ([(Text, Text)] -> Form)
-> Either Text [(Text, Text)] -> Either Text Form
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Text, Text)] -> Form
forall a. ToForm a => a -> Form
toForm (Either Text [(Text, Text)] -> Either Text Form)
-> (ByteString -> Either Text [(Text, Text)])
-> ByteString
-> Either Text Form
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either Text [(Text, Text)]
urlDecodeParams
urlDecodeParams :: BSL.ByteString -> Either Text [(Text, Text)]
urlDecodeParams :: ByteString -> Either Text [(Text, Text)]
urlDecodeParams ByteString
bs = ([ByteString] -> Either Text (Text, Text))
-> [[ByteString]] -> Either Text [(Text, Text)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse [ByteString] -> Either Text (Text, Text)
parsePair [[ByteString]]
pairs
where
pairs :: [[ByteString]]
pairs = (ByteString -> [ByteString]) -> [ByteString] -> [[ByteString]]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> ByteString -> [ByteString]
BSL8.split Char
'=') (Char -> ByteString -> [ByteString]
BSL8.split Char
'&' ByteString
bs)
unescape :: ByteString -> Text
unescape = OnDecodeError -> ByteString -> Text
Text.decodeUtf8With OnDecodeError
lenientDecode (ByteString -> Text)
-> (ByteString -> ByteString) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> ByteString -> ByteString
urlDecode Bool
True (ByteString -> ByteString)
-> (ByteString -> ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.toStrict
parsePair :: [ByteString] -> Either Text (Text, Text)
parsePair [ByteString]
p =
case (ByteString -> Text) -> [ByteString] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Text
unescape [ByteString]
p of
[Text
k, Text
v] -> (Text, Text) -> Either Text (Text, Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Text
k, Text
v)
[Text
k] -> (Text, Text) -> Either Text (Text, Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (Text
k, Text
"")
[Text]
xs -> Text -> Either Text (Text, Text)
forall a b. a -> Either a b
Left (Text -> Either Text (Text, Text))
-> Text -> Either Text (Text, Text)
forall a b. (a -> b) -> a -> b
$ Text
"not a valid pair: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
Text.intercalate Text
"=" [Text]
xs
urlDecodeAsForm :: FromForm a => BSL.ByteString -> Either Text a
urlDecodeAsForm :: ByteString -> Either Text a
urlDecodeAsForm = Form -> Either Text a
forall a. FromForm a => Form -> Either Text a
fromForm (Form -> Either Text a)
-> (ByteString -> Either Text Form) -> ByteString -> Either Text a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ByteString -> Either Text Form
urlDecodeForm
urlEncodeAsForm :: ToForm a => a -> BSL.ByteString
urlEncodeAsForm :: a -> ByteString
urlEncodeAsForm = Form -> ByteString
urlEncodeForm (Form -> ByteString) -> (a -> Form) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Form
forall a. ToForm a => a -> Form
toForm
urlEncodeAsFormStable :: ToForm a => a -> BSL.ByteString
urlEncodeAsFormStable :: a -> ByteString
urlEncodeAsFormStable = Form -> ByteString
urlEncodeFormStable (Form -> ByteString) -> (a -> Form) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Form
forall a. ToForm a => a -> Form
toForm
lookupAll :: Text -> Form -> [Text]
lookupAll :: Text -> Form -> [Text]
lookupAll Text
key = Maybe [Text] -> [Text]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
F.concat (Maybe [Text] -> [Text])
-> (Form -> Maybe [Text]) -> Form -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> HashMap Text [Text] -> Maybe [Text]
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
key (HashMap Text [Text] -> Maybe [Text])
-> (Form -> HashMap Text [Text]) -> Form -> Maybe [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Form -> HashMap Text [Text]
unForm
lookupMaybe :: Text -> Form -> Either Text (Maybe Text)
lookupMaybe :: Text -> Form -> Either Text (Maybe Text)
lookupMaybe Text
key Form
form =
case Text -> Form -> [Text]
lookupAll Text
key Form
form of
[] -> Maybe Text -> Either Text (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing
[Text
v] -> Maybe Text -> Either Text (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
v)
[Text]
_ -> Text -> Either Text (Maybe Text)
forall a b. a -> Either a b
Left (Text -> Either Text (Maybe Text))
-> Text -> Either Text (Maybe Text)
forall a b. (a -> b) -> a -> b
$ Text
"Duplicate key " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Text -> String
forall a. Show a => a -> String
show Text
key)
lookupUnique :: Text -> Form -> Either Text Text
lookupUnique :: Text -> Form -> Either Text Text
lookupUnique Text
key Form
form = do
Maybe Text
mv <- Text -> Form -> Either Text (Maybe Text)
lookupMaybe Text
key Form
form
case Maybe Text
mv of
Just Text
v -> Text -> Either Text Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
v
Maybe Text
Nothing -> Text -> Either Text Text
forall a b. a -> Either a b
Left (Text -> Either Text Text) -> Text -> Either Text Text
forall a b. (a -> b) -> a -> b
$ Text
"Could not find key " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Text -> String
forall a. Show a => a -> String
show Text
key)
parseAll :: FromHttpApiData v => Text -> Form -> Either Text [v]
parseAll :: Text -> Form -> Either Text [v]
parseAll Text
key = [Text] -> Either Text [v]
forall (t :: * -> *) a.
(Traversable t, FromHttpApiData a) =>
t Text -> Either Text (t a)
parseQueryParams ([Text] -> Either Text [v])
-> (Form -> [Text]) -> Form -> Either Text [v]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Form -> [Text]
lookupAll Text
key
parseMaybe :: FromHttpApiData v => Text -> Form -> Either Text (Maybe v)
parseMaybe :: Text -> Form -> Either Text (Maybe v)
parseMaybe Text
key = Maybe Text -> Either Text (Maybe v)
forall (t :: * -> *) a.
(Traversable t, FromHttpApiData a) =>
t Text -> Either Text (t a)
parseQueryParams (Maybe Text -> Either Text (Maybe v))
-> (Form -> Either Text (Maybe Text))
-> Form
-> Either Text (Maybe v)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Text -> Form -> Either Text (Maybe Text)
lookupMaybe Text
key
parseUnique :: FromHttpApiData v => Text -> Form -> Either Text v
parseUnique :: Text -> Form -> Either Text v
parseUnique Text
key Form
form = Text -> Form -> Either Text Text
lookupUnique Text
key Form
form Either Text Text -> (Text -> Either Text v) -> Either Text v
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Either Text v
forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam
data FormOptions = FormOptions
{
FormOptions -> ShowS
fieldLabelModifier :: String -> String
}
defaultFormOptions :: FormOptions
defaultFormOptions :: FormOptions
defaultFormOptions = FormOptions :: ShowS -> FormOptions
FormOptions
{ fieldLabelModifier :: ShowS
fieldLabelModifier = ShowS
forall a. a -> a
id
}
sortOn :: Ord b => (a -> b) -> [a] -> [a]
sortOn :: (a -> b) -> [a] -> [a]
sortOn a -> b
f = (a -> a -> Ordering) -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((a -> b) -> a -> a -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing a -> b
f)