{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
module Text.URI.QQ
( uri
, scheme
, host
, username
, password
, pathPiece
, queryKey
, queryValue
, fragment )
where
import Control.Exception (SomeException, Exception (..))
import Data.Data (Data)
import Data.Text (Text)
import Data.Typeable (cast)
import Language.Haskell.TH
import Language.Haskell.TH.Quote (QuasiQuoter (..))
import Language.Haskell.TH.Syntax (lift)
import Text.URI.Parser.Text
import Text.URI.Types
import qualified Data.Text as T
#if MIN_VERSION_template_haskell(2,11,0)
import Language.Haskell.TH.Syntax (dataToExpQ)
#else
dataToExpQ :: Data a => (forall b. Data b => b -> Maybe (Q Exp)) -> a -> Q Exp
dataToExpQ _ _ = fail "The feature requires at least GHC 8 to work"
#endif
uri :: QuasiQuoter
uri = liftToQQ mkURI
scheme :: QuasiQuoter
scheme = liftToQQ mkScheme
host :: QuasiQuoter
host = liftToQQ mkHost
username :: QuasiQuoter
username = liftToQQ mkUsername
password :: QuasiQuoter
password = liftToQQ mkPassword
pathPiece :: QuasiQuoter
pathPiece = liftToQQ mkPathPiece
queryKey :: QuasiQuoter
queryKey = liftToQQ mkQueryKey
queryValue :: QuasiQuoter
queryValue = liftToQQ mkQueryValue
fragment :: QuasiQuoter
fragment = liftToQQ mkFragment
liftToQQ :: Data a => (Text -> Either SomeException a) -> QuasiQuoter
liftToQQ f = QuasiQuoter
{ quoteExp = \str ->
case f (T.pack str) of
Left err -> fail (displayException err)
Right x -> dataToExpQ (fmap liftText . cast) x
, quotePat = error "This usage is not supported"
, quoteType = error "This usage is not supported"
, quoteDec = error "This usage is not supported" }
liftText :: Text -> Q Exp
liftText txt = AppE (VarE 'T.pack) <$> lift (T.unpack txt)