Removed bad undefineds

This commit is contained in:
Michael Snoyman 2009-12-14 19:50:16 +02:00
parent 32f3ed04eb
commit b78a16e938
6 changed files with 85 additions and 49 deletions

View File

@ -1,3 +1,4 @@
{-# LANGUAGE TemplateHaskell #-}
--------------------------------------------------------- ---------------------------------------------------------
-- --
-- Module : Yesod -- Module : Yesod

View File

@ -81,21 +81,28 @@ instance MonadRequestReader (Handler yesod) where
getYesod :: Handler yesod yesod getYesod :: Handler yesod yesod
getYesod = Handler $ \(_, yesod) -> return ([], HCContent yesod) getYesod = Handler $ \(_, yesod) -> return ([], HCContent yesod)
-- FIXME this is a stupid signature runHandler :: Handler yesod RepChooser
runHandler :: HasReps a -> (ErrorResult -> Handler yesod RepChooser)
=> Handler yesod a
-> RawRequest -> RawRequest
-> yesod -> yesod
-> [ContentType] -> [ContentType]
-> IO (Either (ErrorResult, [Header]) Response) -> IO Response
runHandler (Handler handler) rr yesod cts = do runHandler (Handler handler) eh rr y cts = do
(headers, contents) <- handler (rr, yesod) (headers, contents) <- Control.Exception.catch
case contents of (handler (rr, y))
HCError e -> return $ Left (InternalError $ show e, headers) (\e -> return ([], HCError (e :: Control.Exception.SomeException)))
HCSpecial e -> return $ Left (e, headers) let contents' =
HCContent a -> case contents of
let (ct, c) = chooseRep a cts HCError e -> Left $ InternalError $ show e
in return $ Right $ Response 200 headers ct c HCSpecial e -> Left e
HCContent a -> Right a
case contents' of
Left e -> do
Response _ hs ct c <- runHandler (eh e) eh rr y cts
return $ Response (getStatus e) hs ct c
Right a ->
let (ct, c) = a cts
in return $ Response 200 headers ct c
{- FIXME {- FIXME
class ToHandler a where class ToHandler a where
toHandler :: a -> Handler toHandler :: a -> Handler

View File

@ -6,6 +6,7 @@
{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TemplateHaskell #-}
--------------------------------------------------------- ---------------------------------------------------------
-- --
-- Module : Yesod.Resource -- Module : Yesod.Resource
@ -22,8 +23,9 @@
module Yesod.Resource module Yesod.Resource
( ResourcePattern ( ResourcePattern
, checkPattern , checkPattern
, checkPatternsTH
, validatePatterns , validatePatterns
, checkResourceName , checkPatterns
#if TEST #if TEST
-- * Testing -- * Testing
, testSuite , testSuite
@ -35,13 +37,16 @@ import Yesod.Definitions
import Data.List (intercalate) import Data.List (intercalate)
import Data.Char (isDigit) import Data.Char (isDigit)
import Control.Monad (when)
import Language.Haskell.TH
import Data.Typeable (Typeable) import Data.Typeable (Typeable)
import Control.Exception (Exception) import Control.Exception (Exception)
import Data.Attempt -- for failure stuff import Data.Attempt -- for failure stuff
import Data.Convertible.Text import Data.Convertible.Text
#if TEST #if TEST
import Control.Monad (replicateM, when) import Control.Monad (replicateM)
import Test.Framework (testGroup, Test) import Test.Framework (testGroup, Test)
import Test.Framework.Providers.HUnit import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck (testProperty) import Test.Framework.Providers.QuickCheck (testProperty)
@ -93,6 +98,11 @@ data CheckPatternReturn =
checkPattern :: RP -> Resource -> Maybe SMap checkPattern :: RP -> Resource -> Maybe SMap
checkPattern = checkPatternPieces . unRP checkPattern = checkPatternPieces . unRP
checkPatternsTH :: Bool -> [ResourcePattern] -> Q Exp
checkPatternsTH toCheck patterns = do
runIO $ when toCheck $ checkPatterns patterns
[|return ()|]
checkPatternPieces :: [RPP] -> Resource -> Maybe SMap checkPatternPieces :: [RPP] -> Resource -> Maybe SMap
checkPatternPieces rp r checkPatternPieces rp r
| not (null rp) && isSlurp (last rp) = do | not (null rp) && isSlurp (last rp) = do
@ -141,10 +151,10 @@ data OverlappingPatterns =
deriving (Show, Typeable) deriving (Show, Typeable)
instance Exception OverlappingPatterns instance Exception OverlappingPatterns
checkResourceName :: MonadFailure OverlappingPatterns f checkPatterns :: MonadFailure OverlappingPatterns f
=> [ResourcePattern] => [ResourcePattern]
-> f () -> f ()
checkResourceName patterns = checkPatterns patterns =
case validatePatterns patterns of case validatePatterns patterns of
[] -> return () [] -> return ()
x -> failure $ OverlappingPatterns x x -> failure $ OverlappingPatterns x

View File

@ -26,6 +26,8 @@ module Yesod.Response
-- * Header -- * Header
, Header (..) , Header (..)
, toPair , toPair
-- * Converting to Hack values
, responseToHackResponse
#if TEST #if TEST
-- * Tests -- * Tests
, testSuite , testSuite
@ -41,6 +43,7 @@ import Yesod.Rep
import Data.Time.Clock import Data.Time.Clock
import Web.Encodings (formatW3) import Web.Encodings (formatW3)
import qualified Hack
#if TEST #if TEST
import Test.Framework (testGroup, Test) import Test.Framework (testGroup, Test)
@ -91,6 +94,15 @@ toPair (DeleteCookie key) = return
key ++ "=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT") key ++ "=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT")
toPair (Header key value) = return (key, value) toPair (Header key value) = return (key, value)
-- FIXME add test
responseToHackResponse :: [String] -- ^ language list
-> Response -> IO Hack.Response
responseToHackResponse _FIXMEls (Response sc hs ct c) = do
hs' <- mapM toPair hs
let hs'' = ("Content-Type", show ct) : hs'
let asLBS = unContent c
return $ Hack.Response sc hs'' asLBS
#if TEST #if TEST
----- Testing ----- Testing
testSuite :: Test testSuite :: Test

View File

@ -12,12 +12,13 @@ import Yesod.Constants
import Yesod.Definitions import Yesod.Definitions
import Yesod.Resource import Yesod.Resource
import Yesod.Handler import Yesod.Handler
import Yesod.Utils
import Control.Monad (when)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Convertible.Text import Data.Convertible.Text
import Web.Encodings import Web.Encodings
import Control.Arrow ((***)) import Control.Arrow ((***))
import Control.Monad (when)
import qualified Hack import qualified Hack
import Hack.Middleware.CleanPath import Hack.Middleware.CleanPath
@ -34,7 +35,7 @@ class Yesod a where
encryptKey _ = getKey defaultKeyFile encryptKey _ = getKey defaultKeyFile
-- | Output error response pages. -- | Output error response pages.
errorHandler :: ErrorResult -> [ContentType] -> Handler a ContentPair errorHandler :: ErrorResult -> Handler a RepChooser
errorHandler = defaultErrorHandler errorHandler = defaultErrorHandler
-- | Whether or not we should check for overlapping resource names. -- | Whether or not we should check for overlapping resource names.
@ -46,24 +47,23 @@ class Yesod a where
defaultErrorHandler :: Yesod y defaultErrorHandler :: Yesod y
=> ErrorResult => ErrorResult
-> [ContentType] -> Handler y RepChooser
-> Handler y ContentPair defaultErrorHandler NotFound = do
defaultErrorHandler NotFound cts = do
rr <- askRawRequest rr <- askRawRequest
return $ chooseRep (toHtmlObject $ "Not found: " ++ show rr) cts return $ chooseRep $ toHtmlObject $ "Not found: " ++ show rr
defaultErrorHandler (Redirect url) cts = defaultErrorHandler (Redirect url) =
return $ chooseRep (toHtmlObject $ "Redirect to: " ++ url) cts return $ chooseRep $ toHtmlObject $ "Redirect to: " ++ url
defaultErrorHandler PermissionDenied cts = defaultErrorHandler PermissionDenied =
return $ chooseRep (toHtmlObject "Permission denied") cts return $ chooseRep $ toHtmlObject "Permission denied"
defaultErrorHandler (InvalidArgs ia) cts = defaultErrorHandler (InvalidArgs ia) =
return $ chooseRep (toHtmlObject return $ chooseRep $ toHtmlObject
[ ("errorMsg", toHtmlObject "Invalid arguments") [ ("errorMsg", toHtmlObject "Invalid arguments")
, ("messages", toHtmlObject ia) , ("messages", toHtmlObject ia)
]) cts ]
defaultErrorHandler (InternalError e) cts = defaultErrorHandler (InternalError e) =
return $ chooseRep (toHtmlObject return $ chooseRep $ toHtmlObject
[ ("Internal server error", e) [ ("Internal server error", e)
]) cts ]
-- | For type signature reasons. -- | For type signature reasons.
handlers' :: Yesod y => y -> handlers' :: Yesod y => y ->
@ -72,8 +72,12 @@ handlers' _ = handlers
toHackApp :: Yesod y => y -> Hack.Application toHackApp :: Yesod y => y -> Hack.Application
toHackApp a env = do toHackApp a env = do
let patterns = map fst $ handlers' a -- FIXME figure out a way to do this check compile-time
when (checkOverlaps a) $ checkResourceName patterns -- FIXME maybe this should be done compile-time? when (checkOverlaps a) $ checkPatterns $ map fst $ handlers' a
toHackAppUnchecked a env
toHackAppUnchecked :: Yesod y => y -> Hack.Application
toHackAppUnchecked a env = do
key <- encryptKey a key <- encryptKey a
let app' = toHackApp' a let app' = toHackApp' a
middleware = middleware =
@ -94,27 +98,28 @@ toHackApp' y env = do
(verbPairs, urlParams'') <- lookupHandlers resource (verbPairs, urlParams'') <- lookupHandlers resource
let verb = cs $ Hack.requestMethod env let verb = cs $ Hack.requestMethod env
handler'' <- lookup verb verbPairs handler'' <- lookup verb verbPairs
return (handler'' types, urlParams'') return (handler'', urlParams'')
rr = envToRawRequest urlParams' env rr = envToRawRequest urlParams' env
runHandler' handler rr y res <- runHandler handler errorHandler rr y types
let langs = ["en"] -- FIXME
responseToHackResponse langs res
httpAccept :: Hack.Env -> [ContentType] httpAccept :: Hack.Env -> [ContentType]
httpAccept = undefined httpAccept = map TypeOther . parseHttpAccept . fromMaybe ""
. lookup "Accept" . Hack.http
lookupHandlers :: Yesod y lookupHandlers :: Yesod y
=> Resource => Resource
-> Maybe -> Maybe
( [(Verb, [ContentType] -> Handler y ContentPair)] ( [(Verb, Handler y RepChooser)]
, [(ParamName, ParamValue)] , [(ParamName, ParamValue)]
) )
lookupHandlers = undefined lookupHandlers r = helper handlers where
helper [] = Nothing
runHandler' :: Yesod y helper ((rps, v):rest) =
=> Handler y ContentPair case checkPattern (cs rps) r of
-> RawRequest Just up -> Just (v, up)
-> y Nothing -> helper rest
-> IO Hack.Response
runHandler' = undefined
envToRawRequest :: [(ParamName, ParamValue)] -> Hack.Env -> RawRequest envToRawRequest :: [(ParamName, ParamValue)] -> Hack.Env -> RawRequest
envToRawRequest urlParams' env = envToRawRequest urlParams' env =

View File

@ -42,7 +42,8 @@ library
containers >= 0.2.0.1 && < 0.3, containers >= 0.2.0.1 && < 0.3,
HStringTemplate >= 0.6.2 && < 0.7, HStringTemplate >= 0.6.2 && < 0.7,
data-object-json >= 0.0.0 && < 0.1, data-object-json >= 0.0.0 && < 0.1,
attempt >= 0.2.1 && < 0.3 attempt >= 0.2.1 && < 0.3,
template-haskell
exposed-modules: Yesod exposed-modules: Yesod
Yesod.Constants Yesod.Constants
Yesod.Rep Yesod.Rep