Initial migration to web-routes-quasi
This commit is contained in:
parent
3854af50f6
commit
a19751622a
@ -4,6 +4,7 @@
|
|||||||
{-# LANGUAGE TypeSynonymInstances #-}
|
{-# LANGUAGE TypeSynonymInstances #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE PackageImports #-}
|
{-# LANGUAGE PackageImports #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
--
|
--
|
||||||
-- Module : Yesod.Handler
|
-- Module : Yesod.Handler
|
||||||
@ -21,8 +22,11 @@ module Yesod.Handler
|
|||||||
( -- * Handler monad
|
( -- * Handler monad
|
||||||
Handler
|
Handler
|
||||||
, getYesod
|
, getYesod
|
||||||
|
, getUrlRender
|
||||||
, runHandler
|
, runHandler
|
||||||
, liftIO
|
, liftIO
|
||||||
|
, YesodApp
|
||||||
|
, Routes
|
||||||
-- * Special handlers
|
-- * Special handlers
|
||||||
, redirect
|
, redirect
|
||||||
, sendFile
|
, sendFile
|
||||||
@ -51,7 +55,14 @@ import Data.Object.Html
|
|||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
|
|
||||||
data HandlerData yesod = HandlerData Request yesod
|
type family Routes y
|
||||||
|
|
||||||
|
data HandlerData yesod = HandlerData Request yesod (Routes yesod -> String)
|
||||||
|
|
||||||
|
type YesodApp yesod = (ErrorResponse -> Handler yesod ChooseRep)
|
||||||
|
-> Request
|
||||||
|
-> [ContentType]
|
||||||
|
-> IO Response
|
||||||
|
|
||||||
------ Handler monad
|
------ Handler monad
|
||||||
newtype Handler yesod a = Handler {
|
newtype Handler yesod a = Handler {
|
||||||
@ -84,27 +95,25 @@ instance MonadIO (Handler yesod) where
|
|||||||
instance Failure ErrorResponse (Handler yesod) where
|
instance Failure ErrorResponse (Handler yesod) where
|
||||||
failure e = Handler $ \_ -> return ([], HCError e)
|
failure e = Handler $ \_ -> return ([], HCError e)
|
||||||
instance RequestReader (Handler yesod) where
|
instance RequestReader (Handler yesod) where
|
||||||
getRequest = Handler $ \(HandlerData rr _)
|
getRequest = Handler $ \(HandlerData rr _ _)
|
||||||
-> return ([], HCContent rr)
|
-> return ([], HCContent rr)
|
||||||
|
|
||||||
getYesod :: Handler yesod yesod
|
getYesod :: Handler yesod yesod
|
||||||
getYesod = Handler $ \(HandlerData _ yesod) -> return ([], HCContent yesod)
|
getYesod = Handler $ \(HandlerData _ yesod _) -> return ([], HCContent yesod)
|
||||||
|
|
||||||
runHandler :: Handler yesod ChooseRep
|
getUrlRender :: Handler yesod (Routes yesod -> String)
|
||||||
-> (ErrorResponse -> Handler yesod ChooseRep)
|
getUrlRender = Handler $ \(HandlerData _ _ r) -> return ([], HCContent r)
|
||||||
-> Request
|
|
||||||
-> yesod
|
runHandler :: HasReps c => Handler yesod c -> yesod -> (Routes yesod -> String) -> YesodApp yesod
|
||||||
-> [ContentType]
|
runHandler handler y render eh rr cts = do
|
||||||
-> IO Response
|
|
||||||
runHandler handler eh rr y cts = do
|
|
||||||
let toErrorHandler =
|
let toErrorHandler =
|
||||||
InternalError
|
InternalError
|
||||||
. (show :: Control.Exception.SomeException -> String)
|
. (show :: Control.Exception.SomeException -> String)
|
||||||
(headers, contents) <- Control.Exception.catch
|
(headers, contents) <- Control.Exception.catch
|
||||||
(unHandler handler $ HandlerData rr y)
|
(unHandler handler $ HandlerData rr y render)
|
||||||
(\e -> return ([], HCError $ toErrorHandler e))
|
(\e -> return ([], HCError $ toErrorHandler e))
|
||||||
let handleError e = do
|
let handleError e = do
|
||||||
Response _ hs ct c <- runHandler (eh e) safeEh rr y cts
|
Response _ hs ct c <- runHandler (eh e) y render safeEh rr cts
|
||||||
let hs' = headers ++ hs
|
let hs' = headers ++ hs
|
||||||
return $ Response (getStatus e) hs' ct c
|
return $ Response (getStatus e) hs' ct c
|
||||||
let sendFile' ct fp = do
|
let sendFile' ct fp = do
|
||||||
@ -119,7 +128,7 @@ runHandler handler eh rr y cts = do
|
|||||||
(sendFile' ct fp)
|
(sendFile' ct fp)
|
||||||
(handleError . toErrorHandler)
|
(handleError . toErrorHandler)
|
||||||
HCContent a -> do
|
HCContent a -> do
|
||||||
(ct, c) <- a cts
|
(ct, c) <- chooseRep a cts
|
||||||
return $ Response W.Status200 headers ct c
|
return $ Response W.Status200 headers ct c
|
||||||
|
|
||||||
safeEh :: ErrorResponse -> Handler yesod ChooseRep
|
safeEh :: ErrorResponse -> Handler yesod ChooseRep
|
||||||
|
|||||||
@ -1,16 +1,29 @@
|
|||||||
---------------------------------------------------------
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
--
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
-- Module : Yesod.Resource
|
|
||||||
-- Copyright : Michael Snoyman
|
|
||||||
-- License : BSD3
|
|
||||||
--
|
|
||||||
-- Maintainer : Michael Snoyman <michael@snoyman.com>
|
|
||||||
-- Stability : Stable
|
|
||||||
-- Portability : portable
|
|
||||||
--
|
|
||||||
-- Defines the ResourceName class.
|
|
||||||
--
|
|
||||||
---------------------------------------------------------
|
|
||||||
module Yesod.Resource
|
module Yesod.Resource
|
||||||
(
|
( parseRoutes
|
||||||
|
, mkYesod
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Web.Routes.Quasi (parseRoutes, createRoutes, Resource (..))
|
||||||
|
import Yesod.Handler
|
||||||
|
import Language.Haskell.TH.Syntax
|
||||||
|
import Yesod.Yesod
|
||||||
|
|
||||||
|
mkYesod :: String -> [Resource] -> Q [Dec]
|
||||||
|
mkYesod name res = do
|
||||||
|
let name' = mkName name
|
||||||
|
let yaname = mkName $ name ++ "YesodApp"
|
||||||
|
let ya = TySynD yaname [] $ ConT ''YesodApp `AppT` ConT name'
|
||||||
|
let tySyn = TySynInstD ''Routes [ConT $ name'] (ConT $ mkName $ name ++ "Routes")
|
||||||
|
let hand = TySynD (mkName $ name ++ "Handler") [PlainTV $ mkName "a"]
|
||||||
|
$ ConT ''Handler `AppT` ConT name' `AppT` VarT (mkName "a")
|
||||||
|
let gsbod = NormalB $ VarE $ mkName $ "site" ++ name ++ "Routes"
|
||||||
|
let yes' = FunD (mkName "getSite") [Clause [] gsbod []]
|
||||||
|
let yes = InstanceD [] (ConT ''YesodSite `AppT` ConT name') [yes']
|
||||||
|
decs <- createRoutes (name ++ "Routes")
|
||||||
|
yaname
|
||||||
|
name'
|
||||||
|
"runHandler"
|
||||||
|
res
|
||||||
|
return $ ya : tySyn : hand : yes : decs
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
-- | The basic typeclass for a Yesod application.
|
-- | The basic typeclass for a Yesod application.
|
||||||
module Yesod.Yesod
|
module Yesod.Yesod
|
||||||
( Yesod (..)
|
( Yesod (..)
|
||||||
|
, YesodSite (..)
|
||||||
, YesodApproot (..)
|
, YesodApproot (..)
|
||||||
, applyLayout'
|
, applyLayout'
|
||||||
, applyLayoutJson
|
, applyLayoutJson
|
||||||
@ -20,6 +21,7 @@ import qualified Data.ByteString as B
|
|||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
import Web.Mime
|
import Web.Mime
|
||||||
import Web.Encodings (parseHttpAccept)
|
import Web.Encodings (parseHttpAccept)
|
||||||
|
import Web.Routes (Site (..))
|
||||||
|
|
||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
import Network.Wai.Middleware.CleanPath
|
import Network.Wai.Middleware.CleanPath
|
||||||
@ -32,11 +34,13 @@ import qualified Network.Wai.Handler.SimpleServer as SS
|
|||||||
import qualified Network.Wai.Handler.CGI as CGI
|
import qualified Network.Wai.Handler.CGI as CGI
|
||||||
import System.Environment (getEnvironment)
|
import System.Environment (getEnvironment)
|
||||||
|
|
||||||
class Yesod a where
|
class YesodSite y where
|
||||||
-- | Please use the Quasi-Quoter, you\'ll be happier. For more information,
|
getSite :: ((String -> YesodApp y) -> YesodApp y) -- ^ get the method
|
||||||
-- see the examples/fact.lhs sample.
|
-> YesodApp y -- ^ bad method
|
||||||
resources :: Resource -> W.Method -> Handler a ChooseRep
|
-> y
|
||||||
|
-> Site (Routes y) (YesodApp y)
|
||||||
|
|
||||||
|
class YesodSite a => Yesod a where
|
||||||
-- | The encryption key to be used for encrypting client sessions.
|
-- | The encryption key to be used for encrypting client sessions.
|
||||||
encryptKey :: a -> IO Word256
|
encryptKey :: a -> IO Word256
|
||||||
encryptKey _ = getKey defaultKeyFile
|
encryptKey _ = getKey defaultKeyFile
|
||||||
@ -62,6 +66,8 @@ class Yesod a where
|
|||||||
onRequest :: a -> Request -> IO ()
|
onRequest :: a -> Request -> IO ()
|
||||||
onRequest _ _ = return ()
|
onRequest _ _ = return ()
|
||||||
|
|
||||||
|
badMethod :: a -> YesodApp a
|
||||||
|
|
||||||
class Yesod a => YesodApproot a where
|
class Yesod a => YesodApproot a where
|
||||||
-- | An absolute URL to the root of the application.
|
-- | An absolute URL to the root of the application.
|
||||||
approot :: a -> Approot
|
approot :: a -> Approot
|
||||||
@ -133,12 +139,24 @@ toWaiApp' :: Yesod y
|
|||||||
-> W.Request
|
-> W.Request
|
||||||
-> IO W.Response
|
-> IO W.Response
|
||||||
toWaiApp' y resource session env = do
|
toWaiApp' y resource session env = do
|
||||||
let types = httpAccept env
|
let site = getSite getMethod (badMethod y) y
|
||||||
handler = resources (map cs resource) $ W.requestMethod env
|
types = httpAccept env
|
||||||
rr <- parseWaiRequest env session
|
pathSegments = map cleanupSegment resource
|
||||||
onRequest y rr
|
eurl = parsePathSegments site pathSegments
|
||||||
res <- runHandler handler errorHandler rr y types
|
case eurl of
|
||||||
responseToWaiResponse res
|
Left _ -> error "FIXME: send 404 message"
|
||||||
|
Right url -> do
|
||||||
|
rr <- parseWaiRequest env session
|
||||||
|
onRequest y rr
|
||||||
|
let render = error "FIXME: render" -- use formatPathSegments
|
||||||
|
res <- handleSite site render url errorHandler rr types
|
||||||
|
responseToWaiResponse res
|
||||||
|
|
||||||
|
getMethod :: (String -> YesodApp y) -> YesodApp y
|
||||||
|
getMethod = error "FIXME: getMethod"
|
||||||
|
|
||||||
|
cleanupSegment :: B.ByteString -> String
|
||||||
|
cleanupSegment = error "FIXME: cleanupSegment"
|
||||||
|
|
||||||
httpAccept :: W.Request -> [ContentType]
|
httpAccept :: W.Request -> [ContentType]
|
||||||
httpAccept = map contentTypeFromBS
|
httpAccept = map contentTypeFromBS
|
||||||
|
|||||||
@ -58,7 +58,9 @@ library
|
|||||||
attempt >= 0.2.1 && < 0.3,
|
attempt >= 0.2.1 && < 0.3,
|
||||||
template-haskell,
|
template-haskell,
|
||||||
failure >= 0.0.0 && < 0.1,
|
failure >= 0.0.0 && < 0.1,
|
||||||
safe-failure >= 0.4.0 && < 0.5
|
safe-failure >= 0.4.0 && < 0.5,
|
||||||
|
web-routes >= 0.20 && < 0.21,
|
||||||
|
web-routes-quasi >= 0.0 && < 0.1
|
||||||
exposed-modules: Yesod
|
exposed-modules: Yesod
|
||||||
Yesod.Request
|
Yesod.Request
|
||||||
Yesod.Response
|
Yesod.Response
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user