@@ -1,7 +1,9 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
2{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DeriveDataTypeable #-}
4{-# LANGUAGE DeriveDataTypeable #-}
4{-# LANGUAGE DeriveGeneric #-}
5{-# LANGUAGE DeriveGeneric #-}
6+{-# LANGUAGE DeriveLift #-}
5{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
8{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7{-# LANGUAGE KindSignatures #-}
9{-# LANGUAGE KindSignatures #-}
@@ -12,6 +14,7 @@
12{-# LANGUAGE RankNTypes #-}
14{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE RecordWildCards #-}
15{-# LANGUAGE RecordWildCards #-}
14{-# LANGUAGE ScopedTypeVariables #-}
16{-# LANGUAGE ScopedTypeVariables #-}
17+{-# LANGUAGE TemplateHaskellQuotes #-}
15{-# LANGUAGE TypeFamilies #-}
18{-# LANGUAGE TypeFamilies #-}
16{-# LANGUAGE UndecidableInstances #-}
19{-# LANGUAGE UndecidableInstances #-}
@@ -145,6 +148,7 @@ module Network.HTTP.Req
145 useHttpURI,
148 useHttpURI,
146 useHttpsURI,
149 useHttpsURI,
149 -- ** Body
153 -- ** Body
@@ -251,10 +255,14 @@ import Data.Maybe (fromMaybe)
251import Data.Proxy
255import Data.Proxy
252import Data.Semigroup hiding (Option, option)
256import Data.Semigroup hiding (Option, option)
253import Data.Text (Text)
257import Data.Text (Text)
258+import qualified Data.Text as T
254import qualified Data.Text.Encoding as T
259import qualified Data.Text.Encoding as T
255−import Data.Typeable (Typeable)
260+import Data.Typeable (Typeable, cast)
256import GHC.Generics
261import GHC.Generics
257import GHC.TypeLits
262import GHC.TypeLits
263+import qualified Language.Haskell.TH as TH
264+import qualified Language.Haskell.TH.Quote as TH
265+import qualified Language.Haskell.TH.Syntax as TH
258import qualified Network.Connection as NC
266import qualified Network.Connection as NC
259import qualified Network.HTTP.Client as L
267import qualified Network.HTTP.Client as L
260import qualified Network.HTTP.Client.Internal as LI
268import qualified Network.HTTP.Client.Internal as LI
@@ -862,6 +870,20 @@ data Url (scheme :: Scheme) = Url Scheme (NonEmpty Text)
862 -- NOTE The second value is the path segments in reversed order.
870 -- NOTE The second value is the path segments in reversed order.
863 deriving (Eq, Ord, Show, Data, Typeable, Generic)
871 deriving (Eq, Ord, Show, Data, Typeable, Generic)
873+-- With template-haskell >=2.15 and text >=1.2.4 Lift can be derived, however
874+-- the derived lift forgets the type of scheme.
875+instance Typeable scheme => TH.Lift (Url scheme) where
877+ TH.dataToExpQ (fmap liftText . cast) url `TH.sigE` case url of
878+ Url Http _ -> [t|Url 'Http|]
879+ Url Https _ -> [t|Url 'Https|]
881+ liftText t = TH.AppE (TH.VarE 'T.pack) <$> TH.lift (T.unpack t)
883+#if MIN_VERSION_template_haskell(2,16,0)
884+ liftTyped url = TH.TExp <$> TH.lift url
865-- | Given host name, produce a 'Url' which has “http” as its scheme and
887-- | Given host name, produce a 'Url' which has “http” as its scheme and
866-- empty path. This also sets port to @80@.
888-- empty path. This also sets port to @80@.
867http :: Text -> Url 'Http
889http :: Text -> Url 'Http
@@ -937,6 +959,27 @@ uriHost uri = case URI.uriAuthority uri of
937 Right URI.Authority {..} ->
959 Right URI.Authority {..} ->
938 Just (URI.unRText authHost)
960 Just (URI.unRText authHost)
962+-- | A quasiquoter to build an 'Url' and 'Option' tuple. The type of the
963+-- generated expression is `('Url' <scheme1>, 'Option' scheme2)` with
964+-- `<scheme1>` being either `Http` or `Https` depending on the input.
965+urlQ :: TH.QuasiQuoter
968+ { quoteExp = \str ->
969+ case URI.mkURI (T.pack str) of
970+ Left err -> fail (displayException err)
971+ Right uri -> case useURI uri of
972+ Nothing -> fail "Not a HTTP or HTTPS URL"
975+ [ either (TH.lift . fst) (TH.lift . fst) eurl,
978+ quotePat = error "This usage is not supported",
979+ quoteType = error "This usage is not supported",
980+ quoteDec = error "This usage is not supported"
940-- | An internal helper function to extract 'Option's from a 'URI'.
983-- | An internal helper function to extract 'Option's from a 'URI'.
941uriOptions :: forall scheme. URI -> Option scheme
984uriOptions :: forall scheme. URI -> Option scheme
942uriOptions uri =
985uriOptions uri =
@@ -1756,7 +1799,7 @@ data Scheme
1757 | -- | HTTPS
1800 | -- | HTTPS
1759− deriving (Eq, Ord, Show, Data, Typeable, Generic)
1802+ deriving (Eq, Ord, Show, Data, Typeable, Generic, TH.Lift)
1761----------------------------------------------------------------------------
1804----------------------------------------------------------------------------
1762-- Constants
1805-- Constants