bird 0.0.8 → 0.0.9
raw patch · 7 files changed
+85/−55 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Bird.Reply: replyToResponse :: Reply -> Response
- Bird.Request: envToRequest :: Env -> Request
- Bird.Request: hackEnvironment :: Request -> Env
- Bird.Request: protocol :: Request -> Hack_UrlScheme
+ Bird.Request: DELETE :: RequestMethod
+ Bird.Request: GET :: RequestMethod
+ Bird.Request: POST :: RequestMethod
+ Bird.Request: PUT :: RequestMethod
+ Bird.Request: data RequestMethod
+ Bird.Request: instance Show RequestMethod
+ Bird.Translator: class BirdReplyTranslator a
+ Bird.Translator: class BirdRequestTranslator a
+ Bird.Translator: fromBirdReply :: (BirdReplyTranslator a) => Reply -> a
+ Bird.Translator: toBirdRequest :: (BirdRequestTranslator a) => a -> Request
+ Bird.Translator.Hack: fromBirdReply :: (BirdReplyTranslator a) => Reply -> a
+ Bird.Translator.Hack: instance BirdReplyTranslator Response
+ Bird.Translator.Hack: instance BirdRequestTranslator Env
+ Bird.Translator.Hack: toBirdRequest :: (BirdRequestTranslator a) => a -> Request
- Bird.Request: Request :: RequestMethod -> Path -> [(String, Maybe String)] -> Hack_UrlScheme -> Env -> Request
+ Bird.Request: Request :: RequestMethod -> Path -> [(String, Maybe String)] -> Request
Files
- bin/bird.hs +11/−8
- bird.cabal +2/−2
- readme.markdown +10/−1
- src/Bird/Reply.hs +0/−10
- src/Bird/Request.hs +9/−34
- src/Bird/Translator.hs +9/−0
- src/Bird/Translator/Hack.hs +44/−0
bin/bird.hs view
@@ -9,8 +9,8 @@ runArg a = case a of - "nest" -> runProcess "ghc" ["--make", "-O2", "Main.hs"] Nothing Nothing Nothing Nothing Nothing >> return ()- "fly" -> runProcess "./Main" [] Nothing Nothing Nothing Nothing Nothing >> return ()+ "nest" -> readProcess "ghc" ["--make", "-O2", "Main.hs"] "" >> return ()+ "fly" -> readProcess "./Main" [] "" >> return () appName -> createBirdApp appName createBirdApp a = do@@ -34,8 +34,11 @@ mainFile a = "import Hack\n" +++ "import qualified Hack as Hack\n" ++ "import Hack.Handler.Happstack\n" ++ "import Bird\n" +++ "import qualified Bird as Bird\n" +++ "import Bird.Translator.Hack\n" ++ "import qualified Control.Monad.State as S\n" ++ "import qualified Control.Monad.Reader as R\n" ++ "import " ++ a ++ "\n" ++ "\n" ++@@ -46,17 +49,17 @@ "route :: Env -> IO Response\n" ++ "route e = response\n" ++ " where \n" ++- " req = envToRequest e\n" +++ " req = toBirdRequest e\n" ++ " response = do \n" ++ " reply <- R.runReaderT (S.execStateT (matchRequest req) def) req\n" ++- " return $ replyToResponse reply\n" ++ "\n" +++ " return $ fromBirdReply reply\n" ++ "\n" ++ "matchRequest r = \n" ++ " case verb r of \n" ++- " GET -> get $ path r\n" ++- " POST -> post $ path r\n" ++- " PUT -> put $ path r\n" ++- " DELETE -> delete $ path r\n" +++ " Bird.GET -> get $ path r\n" +++ " Bird.POST -> post $ path r\n" +++ " Bird.PUT -> put $ path r\n" +++ " Bird.DELETE -> delete $ path r\n" ++ " _ -> error \"not supported\"\n" ++ "\n" ++ "main = run app\n"
bird.cabal view
@@ -1,5 +1,5 @@ Name: bird-Version: 0.0.8+Version: 0.0.9 Build-type: Simple Synopsis: A simple, sinatra-inspired web framework. Description: Bird is a hack-compatible framework for simple websites.@@ -19,5 +19,5 @@ library build-depends: haskell98, mtl >= 1.1.0.2, process, containers, parsec >= 2.1.0.1, bytestring, base >= 4.0 && < 5, hack >= 2009.10.30, hack-handler-happstack, data-default >= 0.2, rallod - exposed-modules: Bird, Bird.Request, Bird.Reply, Bird.Reply.Codes, Bird.Request.QueryStringParser, Bird.BirdRouter+ exposed-modules: Bird, Bird.Request, Bird.Reply, Bird.Reply.Codes, Bird.Request.QueryStringParser, Bird.BirdRouter, Bird.Translator, Bird.Translator.Hack hs-source-dirs: src/
readme.markdown view
@@ -30,8 +30,13 @@ ## Try it out λ curl http://localhost:3000- 404 Not Found+ Hello, Bird!+ + λ curl http://localhost:3000?name=moonmaster9000+ Hello, moonmaster9000 ++ ## Improvise! -- MyApp.hs@@ -40,6 +45,10 @@ import Data.String.Utils get, post, put, delete :: Path -> BirdRouter ()+ get [] = do+ name <- param "name"+ body $ "Hello, " ++ (maybe "Bird!" id name)+ get ("howdy":xs) = body $ "Howdy " ++ (join ", " xs) ++ "!" get ["droids"] = do
src/Bird/Reply.hs view
@@ -1,8 +1,6 @@ module Bird.Reply where import qualified Data.Map as Hash-import Data.ByteString.Lazy.Char8 (pack)-import qualified Hack as Hack import Data.Default data Reply = @@ -15,11 +13,3 @@ instance Default Reply where def = Reply { replyMime = "text/html", replyBody = "", replyStatus = 200, replyHeaders = Hash.empty }--replyToResponse :: Reply -> Hack.Response-replyToResponse r = - Hack.Response {- Hack.status = replyStatus r,- Hack.headers = [("Content-Type", replyMime r)] ++ (Hash.toList $ replyHeaders r),- Hack.body = pack $ replyBody r- }
src/Bird/Request.hs view
@@ -1,45 +1,20 @@ module Bird.Request(- Request(..),- Path,- envToRequest+ Request(..)+, RequestMethod(..)+, Path ) where--import Hack import Data.Default-import Data.ByteString.Lazy.Char8 (pack)-import Rallod-import Text.ParserCombinators.Parsec-import Numeric-import Bird.Request.QueryStringParser type Path = [String] +data RequestMethod = GET | POST | PUT | DELETE deriving(Show)+ data Request = Request { - verb :: RequestMethod,- path :: Path,- params :: [(String, Maybe String)],- protocol :: Hack_UrlScheme,- hackEnvironment :: Env+ verb :: RequestMethod+ , path :: Path+ , params :: [(String, Maybe String)] } deriving (Show) instance Default Request where- def = Request { verb = GET, path = [], params = [], protocol = HTTP, hackEnvironment = def }--envToRequest :: Env -> Request-envToRequest e = - Request {- verb = requestMethod e,- path = split '/' $ pathInfo e,- params = parseQueryString $ queryString e,- protocol = hackUrlScheme e,- hackEnvironment = e- }--split :: Char -> String -> [String]-split d s- | findSep == [] = []- | otherwise = t : split d s''- where- (t, s'') = break (== d) findSep- findSep = dropWhile (== d) s+ def = Request { verb = GET, path = [], params = [] }
+ src/Bird/Translator.hs view
@@ -0,0 +1,9 @@+module Bird.Translator where+import Bird.Reply+import Bird.Request++class BirdReplyTranslator a where+ fromBirdReply :: Reply -> a++class BirdRequestTranslator a where+ toBirdRequest :: a -> Request
+ src/Bird/Translator/Hack.hs view
@@ -0,0 +1,44 @@+module Bird.Translator.Hack(+ fromBirdReply+, toBirdRequest+) where++import qualified Hack as Hack+import qualified Data.Map as Hash+import Bird.Translator+import Bird.Request+import Bird.Reply+import Bird.Request.QueryStringParser+import Data.ByteString.Lazy.Char8 (pack)++instance BirdReplyTranslator Hack.Response where+ fromBirdReply r = + Hack.Response {+ Hack.status = replyStatus r,+ Hack.headers = [("Content-Type", replyMime r)] ++ (Hash.toList $ replyHeaders r),+ Hack.body = pack $ replyBody r+ }++instance BirdRequestTranslator Hack.Env where+ toBirdRequest e = + Request {+ verb = hackRequestMethodToBirdRequestMethod $ Hack.requestMethod e+ , path = split '/' $ Hack.pathInfo e+ , params = parseQueryString $ Hack.queryString e+ }++hackRequestMethodToBirdRequestMethod rm = + case rm of + Hack.GET -> GET+ Hack.PUT -> PUT+ Hack.POST -> POST+ Hack.DELETE -> DELETE+ _ -> error "unknown request method!"++split :: Char -> String -> [String]+split d s+ | findSep == [] = []+ | otherwise = t : split d s''+ where+ (t, s'') = break (== d) findSep+ findSep = dropWhile (== d) s