packages feed

apiary 0.5.1.0 → 0.6.0.0

raw patch · 12 files changed

+323/−269 lines, 12 filesdep +reflectionPVP ok

version bump matches the API change (PVP)

Dependencies added: reflection

API changes (from Hackage documentation)

- Control.Monad.Apiary: action_ :: Monad m => ActionT m () -> ApiaryT c m ()
- Control.Monad.Apiary.Action: getQuery :: Monad m => ByteString -> ActionT m (Maybe (Maybe ByteString))
- Control.Monad.Apiary.Action: getQuery' :: Monad m => ByteString -> ActionT m (Maybe ByteString)
- Control.Monad.Apiary.Action: getRequestHeader :: Monad m => HeaderName -> ActionT m (Maybe ByteString)
- Control.Monad.Apiary.Action: getRequestHeader' :: Monad m => HeaderName -> ActionT m ByteString
- Control.Monad.Apiary.Filter: maybeQueryFirst :: Monad m => ByteString -> ApiaryT (Snoc as (Maybe (Maybe ByteString))) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: maybeQueryFirst' :: Monad m => ByteString -> ApiaryT (Snoc as (Maybe ByteString)) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: pCheck :: Proxy a -> Proxy (Check a)
- Control.Monad.Apiary.Filter: pFirst :: Proxy a -> Proxy (First a)
- Control.Monad.Apiary.Filter: pMany :: Proxy a -> Proxy (Many a)
- Control.Monad.Apiary.Filter: pOne :: Proxy a -> Proxy (One a)
- Control.Monad.Apiary.Filter: pOption :: Proxy a -> Proxy (Option a)
- Control.Monad.Apiary.Filter: pSome :: Proxy a -> Proxy (Some a)
- Control.Monad.Apiary.Filter: queryAll :: Monad m => ByteString -> ApiaryT (Snoc as [Maybe ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: queryAll' :: Monad m => ByteString -> ApiaryT (Snoc as [ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: queryFirst :: Monad m => ByteString -> ApiaryT (Snoc as (Maybe ByteString)) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: queryFirst' :: Monad m => ByteString -> ApiaryT (Snoc as ByteString) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: queryMany :: Monad m => ByteString -> ApiaryT (Snoc as [Maybe ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: queryMany' :: Monad m => ByteString -> ApiaryT (Snoc as [ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: querySome :: Monad m => ByteString -> ApiaryT (Snoc as [Maybe ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter: querySome' :: Monad m => ByteString -> ApiaryT (Snoc as [ByteString]) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter.Internal.Query: class Strategy (w :: * -> *) where type family SNext w (as :: [*]) a :: [*]
- Control.Monad.Apiary.Filter.Internal.Query: data Check a
- Control.Monad.Apiary.Filter.Internal.Query: data First a
- Control.Monad.Apiary.Filter.Internal.Query: data Many a
- Control.Monad.Apiary.Filter.Internal.Query: data One a
- Control.Monad.Apiary.Filter.Internal.Query: data Option a
- Control.Monad.Apiary.Filter.Internal.Query: data Some a
- Control.Monad.Apiary.Filter.Internal.Query: getQuery :: Query a => Proxy (w a) -> ByteString -> Query -> [Maybe a]
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy Check
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy First
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy Many
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy One
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy Option
- Control.Monad.Apiary.Filter.Internal.Query: instance Strategy Some
- Control.Monad.Apiary.Filter.Internal.Query: pCheck :: Proxy a -> Proxy (Check a)
- Control.Monad.Apiary.Filter.Internal.Query: pFirst :: Proxy a -> Proxy (First a)
- Control.Monad.Apiary.Filter.Internal.Query: pMany :: Proxy a -> Proxy (Many a)
- Control.Monad.Apiary.Filter.Internal.Query: pOne :: Proxy a -> Proxy (One a)
- Control.Monad.Apiary.Filter.Internal.Query: pOption :: Proxy a -> Proxy (Option a)
- Control.Monad.Apiary.Filter.Internal.Query: pSome :: Proxy a -> Proxy (Some a)
- Control.Monad.Apiary.Filter.Internal.Query: query :: (Query a, Strategy w, Monad m) => ByteString -> Proxy (w a) -> ApiaryT (SNext w as a) m b -> ApiaryT as m b
- Control.Monad.Apiary.Filter.Internal.Query: readStrategy :: (Strategy w, Query a) => ByteString -> Proxy (w a) -> Query -> SList as -> Maybe (SList (SNext w as a))
+ Control.Monad.Apiary.Action: getHeaders :: Monad m => ActionT m RequestHeaders
+ Control.Monad.Apiary.Filter: eqHeader :: Monad m => HeaderName -> ByteString -> ApiaryT as m b -> ApiaryT as m b
+ Control.Monad.Apiary.Filter: hasHeader :: Monad m => HeaderName -> ApiaryT as m b -> ApiaryT as m b
+ Control.Monad.Apiary.Filter: header :: Monad m => HeaderName -> ApiaryT (Snoc as ByteString) m b -> ApiaryT as m b
+ Control.Monad.Apiary.Filter: header' :: (Strategy w, Monad m) => (forall x. Proxy x -> Proxy (w x)) -> (Header -> Bool) -> ApiaryT (SNext w as ByteString) m b -> ApiaryT as m b
+ Control.Monad.Apiary.Filter: headers :: Monad m => HeaderName -> ApiaryT (Snoc as [ByteString]) m b -> ApiaryT as m b
+ Control.Monad.Apiary.Filter.Internal.Strategy: class Strategy (w :: * -> *) where type family SNext w (as :: [*]) a :: [*]
+ Control.Monad.Apiary.Filter.Internal.Strategy: data Check a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data First a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data LimitSome u a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data Many a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data One a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data Option a
+ Control.Monad.Apiary.Filter.Internal.Strategy: data Some a
+ Control.Monad.Apiary.Filter.Internal.Strategy: getQuery :: (v -> Maybe a) -> Proxy (w a) -> ((k, v) -> Bool) -> [(k, v)] -> [Maybe a]
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Reifies * u Int => Strategy (LimitSome u)
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy Check
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy First
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy Many
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy One
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy Option
+ Control.Monad.Apiary.Filter.Internal.Strategy: instance Strategy Some
+ Control.Monad.Apiary.Filter.Internal.Strategy: pCheck :: Proxy a -> Proxy (Check a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: pFirst :: Proxy a -> Proxy (First a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: pMany :: Proxy a -> Proxy (Many a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: pOne :: Proxy a -> Proxy (One a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: pOption :: Proxy a -> Proxy (Option a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: pSome :: Proxy a -> Proxy (Some a)
+ Control.Monad.Apiary.Filter.Internal.Strategy: readStrategy :: Strategy w => (v -> Maybe a) -> ((k, v) -> Bool) -> Proxy (w a) -> [(k, v)] -> SList as -> Maybe (SList (SNext w as a))
+ Control.Monad.Apiary.Filter.Internal.Strategy: reflectLimit :: Reifies n Int => Proxy (LimitSome n a) -> Int
+ Data.Apiary.Param: instance Path Bool
+ Data.Apiary.Param: instance Query Bool
+ Data.Apiary.Param: jsToBool :: (IsString a, Eq a) => a -> Bool
+ Data.Apiary.Param: pBool :: Proxy Bool
+ Data.Apiary.Param: pWord16 :: Proxy Word16
+ Web.Apiary: act :: QuasiQuoter

Files

apiary.cabal view
@@ -1,6 +1,5 @@ name:                apiary-version:             0.5.1.0-x-revision:          1+version:             0.6.0.0 synopsis:            Simple web framework inspired by scotty. description:   Simple web framework inspired by scotty.@@ -58,7 +57,7 @@                        Control.Monad.Apiary.Filter                        Control.Monad.Apiary.Filter.Internal                        Control.Monad.Apiary.Filter.Internal.Capture-                       Control.Monad.Apiary.Filter.Internal.Query+                       Control.Monad.Apiary.Filter.Internal.Strategy                        Control.Monad.Apiary.Action                         Data.Apiary.SList@@ -67,6 +66,7 @@   other-modules:       Control.Monad.Apiary.Internal                        Control.Monad.Apiary.Action.Internal                        Control.Monad.Apiary.Filter.Internal.Capture.TH+                       Web.Apiary.TH   other-extensions:    KindSignatures                      , DataKinds                      , TypeOperators@@ -89,6 +89,7 @@                      , monad-logger       >=0.3 && <0.4                      , data-default-class >=0.0 && <0.1                      , tagged             >=0.7 && <0.8+                     , reflection         >=1.4 && <1.5                       , http-types        >=0.8 && <0.9                      , mime-types        >=0.1 && <0.2
src/Control/Monad/Apiary.hs view
@@ -6,7 +6,7 @@     -- * getter     , apiaryConfig     -- * execute action-    , action, action_, actionWithPreAction+    , action, actionWithPreAction     ) where  import Control.Monad.Apiary.Internal
src/Control/Monad/Apiary/Action.hs view
@@ -7,8 +7,7 @@      -- ** getter     , getRequest-    , getQuery, getQuery'-    , getRequestHeader, getRequestHeader'+    , getHeaders      -- ** setter     , status
src/Control/Monad/Apiary/Action/Internal.hs view
@@ -181,6 +181,7 @@ stopWith :: Monad m => Response -> ActionT m a stopWith a = ActionT $ \_ _ _ _ -> return $ Stop a +-- | get raw request. since 0.1.0.0. getRequest :: Monad m => ActionT m Request getRequest = ActionT $ \_ r s c -> c r s @@ -190,36 +191,28 @@ modifyState :: Monad m => (ActionState -> ActionState) -> ActionT m () modifyState f = ActionT $ \_ _ s c -> c () (f s) --- | when request header is not found, mzero(pass next handler).-getRequestHeader' :: Monad m => HeaderName -> ActionT m S.ByteString-getRequestHeader' h = getRequestHeader h >>= maybe mzero return--getRequestHeader :: Monad m => HeaderName -> ActionT m (Maybe S.ByteString)-getRequestHeader h = (lookup h . requestHeaders) `liftM` getRequest---- | when query parameter is not found, mzero(pass next handler).-getQuery' :: Monad m => S.ByteString -> ActionT m (Maybe S.ByteString)-getQuery' q = getQuery q >>= maybe mzero return--{-# DEPRECATED getQuery' "use qeury derived filter." #-}--getQuery :: Monad m => S.ByteString -> ActionT m (Maybe (Maybe S.ByteString))-getQuery q = (lookup q . queryString) `liftM` getRequest--{-# DEPRECATED getQuery "use qeury derived filter." #-}+-- | get all request headers. since 0.6.0.0.+getHeaders :: Monad m => ActionT m RequestHeaders+getHeaders = requestHeaders `liftM` getRequest +-- | set status code. since 0.1.0.0. status :: Monad m => Status -> ActionT m () status st = modifyState (\s -> s { actionStatus = st } ) +-- | modify response header. since 0.1.0.0. modifyHeader :: Monad m => (ResponseHeaders -> ResponseHeaders) -> ActionT m () modifyHeader f = modifyState (\s -> s {actionHeaders = f $ actionHeaders s } ) +-- | add response header. since 0.1.0.0. addHeader :: Monad m => HeaderName -> S.ByteString -> ActionT m () addHeader h v = modifyHeader ((h,v):) +-- | set response headers. since 0.1.0.0. setHeaders :: Monad m => ResponseHeaders -> ActionT m () setHeaders hs = modifyHeader (const hs) +-- | set content-type header.+-- if content-type header already exists, replace it. since 0.1.0.0. contentType :: Monad m => S.ByteString -> ActionT m () contentType c = modifyHeader     (\h -> ("Content-Type", c) : filter (("Content-Type" /=) . fst) h)@@ -252,21 +245,25 @@ redirectTemporary   :: Monad m => S.ByteString -> ActionT m a redirectTemporary   = redirect temporaryRedirect307 --- | set body to file content and detect Content-Type by extension.+-- | set response body file content and detect Content-Type by extension. since 0.1.0.0. file :: Monad m => FilePath -> Maybe FilePart -> ActionT m () file f p = do     mime <- mimeType <$> getConfig     contentType (mime f)     file' f p +-- | set response body file content, without set Content-Type. since 0.1.0.0. file' :: Monad m => FilePath -> Maybe FilePart -> ActionT m () file' f p = modifyState (\s -> s { actionBody = File f p } ) +-- | set response body builder. since 0.1.0.0. builder :: Monad m => Builder -> ActionT m () builder b = modifyState (\s -> s { actionBody = Builder b } ) +-- | set response body lazy bytestring. since 0.1.0.0. lbs :: Monad m => L.ByteString -> ActionT m () lbs l = modifyState (\s -> s { actionBody = LBS l } ) +-- | set response body source. since 0.1.0.0. source :: Monad m => Source IO (Flush Builder) -> ActionT m () source src = modifyState (\s -> s { actionBody = SRC src } )
src/Control/Monad/Apiary/Filter.hs view
@@ -2,6 +2,9 @@ {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DataKinds #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}  module Control.Monad.Apiary.Filter (     -- * filters@@ -16,24 +19,26 @@      -- ** query matcher     , query-    , pFirst, pOne, pOption, pCheck, pMany, pSome     -- *** specified operators     , (=:), (=!:), (=?:), (?:), (=*:), (=+:)     , hasQuery +    -- ** header matcher+    , hasHeader+    , eqHeader+    , headers+    , header+    , header'      -- ** other     , ssl          -- * Reexport-    -- StdMethod(..)+    -- | StdMethod(..)     , module Network.HTTP.Types-    -- * deprecated-    , queryAll,        queryAll'-    , querySome,       querySome'-    , queryFirst,      queryFirst'-    , queryMany,       queryMany'-    , maybeQueryFirst, maybeQueryFirst'+    -- | Strategy Proxies+    , module Control.Monad.Apiary.Filter.Internal.Strategy+     ) where  import Control.Monad@@ -41,18 +46,28 @@ import qualified Network.HTTP.Types as HT import Network.HTTP.Types (StdMethod(..)) import qualified Data.ByteString as S-import Data.Maybe import Data.Proxy+import Data.Reflection  import Data.Apiary.SList import Data.Apiary.Param  import Control.Monad.Apiary.Action.Internal import Control.Monad.Apiary.Filter.Internal-import Control.Monad.Apiary.Filter.Internal.Query+import qualified Control.Monad.Apiary.Filter.Internal.Strategy as Strategy+import Control.Monad.Apiary.Filter.Internal.Strategy (pFirst, pOne, pOption, pCheck, pMany, pSome) import Control.Monad.Apiary.Filter.Internal.Capture.TH import Control.Monad.Apiary.Internal +-- | filter by HTTP method. since 0.1.0.0.+method :: Monad m => HT.Method -> ApiaryT c m a -> ApiaryT c m a+method m = function_ ((m ==) . requestMethod)++-- | filter by HTTP method using StdMethod. since 0.1.0.0.+stdMethod :: Monad m => StdMethod -> ApiaryT c m a -> ApiaryT c m a+stdMethod = method . HT.renderStdMethod++-- | filter by ssl accessed. since 0.1.0.0. ssl :: Monad m => ApiaryT c m a -> ApiaryT c m a ssl = function_ isSecure @@ -72,18 +87,33 @@ http11 :: Monad m => ApiaryT c m b -> ApiaryT c m b http11 = Control.Monad.Apiary.Filter.httpVersion HT.http11 -method :: Monad m => HT.Method -> ApiaryT c m a -> ApiaryT c m a-method m = function_ ((m ==) . requestMethod)--stdMethod :: Monad m => StdMethod -> ApiaryT c m a -> ApiaryT c m a-stdMethod = method . HT.renderStdMethod- -- | filter by 'Control.Monad.Apiary.Action.rootPattern' of 'Control.Monad.Apiary.Action.ApiaryConfig'. root :: Monad m => ApiaryT c m b -> ApiaryT c m b root m = do     rs <- rootPattern `liftM` apiaryConfig     function_ (\r -> rawPathInfo r `elem` rs) m +-- | low level query getter. since 0.5.0.0.+--+-- @+-- query "key" (Proxy :: Proxy (fetcher type))+-- @+--+-- examples:+--+-- @+-- query "key" (Proxy :: Proxy ('First' Int)) -- get first \'key\' query parameter as Int.+-- query "key" (Proxy :: Proxy ('Option' (Maybe Int)) -- get first \'key\' query parameter as Int. allow without param or value.+-- query "key" (Proxy :: Proxy ('Many' String) -- get all \'key\' query parameter as String.+-- @+-- +query :: (Query a, Strategy.Strategy w, Monad m)+      => S.ByteString+      -> Proxy (w a)+      -> ApiaryT (Strategy.SNext w as a) m b+      -> ApiaryT as m b+query k p = function $ \l r -> Strategy.readStrategy readQuery ((k ==) . fst) p (queryString r) l+ -- | get first matched paramerer. since 0.5.0.0. -- -- @@@ -151,74 +181,41 @@ -- @ -- hasQuery :: Monad m => S.ByteString -> ApiaryT c m a -> ApiaryT c m a-hasQuery q = query q (Proxy :: Proxy (Check ()))+hasQuery q = query q (Proxy :: Proxy (Strategy.Check ()))  -------------------------------------------------------------------------------- -{-# DEPRECATED queryMany, querySome, queryAll, queryMany', querySome', queryAll'-  , maybeQueryFirst, queryFirst, maybeQueryFirst'-  , queryFirst' "use query related filters" #-}---- | get [0,) parameters by query parameter allows empty value. since 0.4.3.0.-queryMany :: Monad m => S.ByteString-          -> ApiaryT (Snoc as [Maybe S.ByteString]) m b-          -> ApiaryT as m b-queryMany q = function' $ Just . map snd . filter ((q ==) . fst) . queryString---- | filter [1,) parameters by query parameter allows empty value. since 0.4.3.0.-querySome :: Monad m => S.ByteString-          -> ApiaryT (Snoc as [Maybe S.ByteString]) m b-          -> ApiaryT as m b-querySome q = function' $ \r -> case map snd . filter ((q ==) . fst) $ queryString r of-    [] -> Nothing-    as -> Just as+-- | check whether to exists specified header or not. since 0.6.0.0.+hasHeader :: Monad m => HT.HeaderName+          -> ApiaryT as m b -> ApiaryT as m b+hasHeader n = header' pCheck ((n ==) . fst) --- | filter by query parameter. since 0.4.0.0.-queryAll :: Monad m => S.ByteString-         -> ApiaryT (Snoc as [Maybe S.ByteString]) m b -- ^ Nothing == no value paramator.+-- | check whether to exists specified valued header or not. since 0.6.0.0.+eqHeader :: Monad m => HT.HeaderName +         -> S.ByteString  -- ^ header value          -> ApiaryT as m b-queryAll = querySome---- | get [0,) parameters by query parameter not allows empty value. since 0.4.3.0.-queryMany' :: Monad m => S.ByteString-           -> ApiaryT (Snoc as [S.ByteString]) m b -           -> ApiaryT as m b-queryMany' q = function' $ Just . mapMaybe snd . filter ((q ==) . fst) . queryString---- | filter [1,) parameters by query parameter not allows empty value. since 0.4.3.0.-querySome' :: Monad m => S.ByteString-           -> ApiaryT (Snoc as [S.ByteString]) m b -           -> ApiaryT as m b-querySome' q = function' $ \r -> case mapMaybe snd . filter ((q ==) . fst) $ queryString r of-    [] -> Nothing-    as -> Just as---- | filter by query parameter. since 0.4.0.0.-queryAll' :: Monad m => S.ByteString-          -> ApiaryT (Snoc as [S.ByteString]) m b -          -> ApiaryT as m b-queryAll' = querySome'+         -> ApiaryT as m b+eqHeader k v = header' pCheck (\(k',v') -> k == k' && v == v') --- | get first query parameter allow empty value. since 0.4.3.0,-maybeQueryFirst :: Monad m => S.ByteString-                -> ApiaryT (Snoc as (Maybe (Maybe S.ByteString))) m b-                -> ApiaryT as m b-maybeQueryFirst q = function' (Just . lookup q . queryString)+-- | filter by header and get first. since 0.6.0.0.+header :: Monad m => HT.HeaderName+       -> ApiaryT (Snoc as S.ByteString) m b -> ApiaryT as m b+header n = header' pFirst ((n ==) . fst) --- | filter by query parameter. allow empty value. since 0.4.0.0.-queryFirst :: Monad m => S.ByteString-           -> ApiaryT (Snoc as (Maybe S.ByteString)) m b-           -> ApiaryT as m b-queryFirst q = function' (lookup q . queryString)+-- | filter by headers up to 100 entries. since 0.6.0.0.+headers :: Monad m => HT.HeaderName+        -> ApiaryT (Snoc as [S.ByteString]) m b -> ApiaryT as m b+headers n = header' limit100 ((n ==) . fst)+  where+    limit100 :: Proxy x -> Proxy (Strategy.LimitSome $(int 100) x)+    limit100 _ = Proxy --- | get first query parameter not allow empty value. since 0.4.3.0,-maybeQueryFirst' :: Monad m => S.ByteString-                 -> ApiaryT (Snoc as (Maybe S.ByteString)) m b-                 -> ApiaryT as m b-maybeQueryFirst' q = function' $ Just . listToMaybe . mapMaybe snd . filter ((q ==) . fst) . queryString+-- | low level header filter. since 0.6.0.0.+header' :: (Strategy.Strategy w, Monad m)+        => (forall x. Proxy x -> Proxy (w x))+        -> (HT.Header -> Bool)+        -> ApiaryT (Strategy.SNext w as S.ByteString) m b+        -> ApiaryT as m b+header' pf kf = function $ \l r ->+    Strategy.readStrategy Just kf (pf pByteString) (requestHeaders r) l --- | filter by query parameter. not allow empty value. since 0.4.0.0.-queryFirst' :: Monad m => S.ByteString-            -> ApiaryT (Snoc as S.ByteString) m b-            -> ApiaryT as m b-queryFirst' q = function' $ listToMaybe . mapMaybe snd . filter ((q ==) . fst) . queryString
src/Control/Monad/Apiary/Filter/Internal/Capture/TH.hs view
@@ -30,6 +30,16 @@ applyCapture :: ExpQ -> ExpQ applyCapture e = [|Capture.capture $e|] +-- | capture QuasiQuoter. since 0.1.0.0.+--+-- example:+--+-- @+-- [capture|\/path|] -- first path == "path"+-- [capture|\/int\/:Int|] -- first path == "int" && get 2nd path as Int.+-- [capture|\/:Int\/:Double|] -- get first path as Int and get 2nd path as Double.+-- @+-- capture :: QuasiQuoter capture = QuasiQuoter      { quoteExp = applyCapture . mkCap . preCap
− src/Control/Monad/Apiary/Filter/Internal/Query.hs
@@ -1,149 +0,0 @@-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}--{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE NoMonomorphismRestriction #-}--module Control.Monad.Apiary.Filter.Internal.Query where--import Control.Monad.Apiary-import Control.Monad.Apiary.Filter.Internal-import Data.Apiary.Param-import Data.Apiary.SList--import Network.Wai-import qualified Network.HTTP.Types as HTTP--import qualified Data.ByteString as S-import Data.Maybe-import Data.Proxy---- | low level query getter. since 0.5.0.0.------ @--- query "key" (Proxy :: Proxy (fetcher type))--- @------ examples:------ @--- query "key" (Proxy :: Proxy ('First' Int)) -- get first \'key\' query parameter as Int.--- query "key" (Proxy :: Proxy ('Option' (Maybe Int)) -- get first \'key\' query parameter as Int. allow without param or value.--- query "key" (Proxy :: Proxy ('Many' String) -- get all \'key\' query parameter as String.--- @--- -query :: (Query a, Strategy w, Monad m)-      => S.ByteString-      -> Proxy (w a)-      -> ApiaryT (SNext w as a) m b-      -> ApiaryT as m b-query k p = function $ \l r -> readStrategy k p (queryString r) l------------------------------------------------------------------------------------class Strategy (w :: * -> *) where-  type SNext w (as :: [*]) a  :: [*]-  readStrategy :: Query a => S.ByteString -> Proxy (w a)-            -> HTTP.Query -> SList as -> Maybe (SList (SNext w as a))--getQuery :: Query a => Proxy (w a) -> S.ByteString -> HTTP.Query -> [Maybe a]-getQuery _ k = map readQuery . map snd . filter ((k ==) . fst)---- | get first matched key( [1,) params to Type.). since 0.5.0.0.-data Option a-instance Strategy Option where-    type SNext Option as a = Snoc as (Maybe a)-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else case catMaybes rs of-               []  -> Just $ sSnoc l (Nothing `asMaybe` p)-               a:_ -> Just $ sSnoc l (Just a)-      where-        asMaybe :: Maybe a -> Proxy (w a) -> Maybe a-        asMaybe a _ = asProxyTypeOf a Proxy---- | get first matched key ( [0,) params to Maybe Type.) since 0.5.0.0.-data First a-instance Strategy First where-    type SNext First as a = Snoc as a-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else case catMaybes rs of-               [] -> Nothing-               a:_ -> Just $ sSnoc l a---- | get key ( [1] param to Type.) since 0.5.0.0.-data One a-instance Strategy One where-    type SNext One as a = Snoc as a-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else case catMaybes rs of-               [a] -> Just $ sSnoc l a-               _   -> Nothing---- | get parameters ( [0,) params to [Type] ) since 0.5.0.0.-data Many a-instance Strategy Many where-    type SNext Many as a = Snoc as [a]-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else Just $ sSnoc l (catMaybes rs)---- | get parameters ( [1,) params to [Type] ) since 0.5.0.0.-data Some a-instance Strategy Some where-    type SNext Some as a = Snoc as [a]-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else case catMaybes rs of-               [] -> Nothing-               as -> Just $ sSnoc l as---- | type check ( [0,) params to No argument ) since 0.5.0.0.-data Check a-instance Strategy Check where-    type SNext Check as a = as-    readStrategy k p q l =-        let rs = getQuery p k q-        in if any isNothing rs-           then Nothing-           else case  catMaybes rs of-               [] -> Nothing-               _  -> Just l---- | construct Option proxy. since 0.5.1.0.-pOption :: Proxy a -> Proxy (Option a)-pOption _ = Proxy---- | construct First proxy. since 0.5.1.0.-pFirst :: Proxy a -> Proxy (First a)-pFirst _ = Proxy---- | construct One proxy. since 0.5.1.0.-pOne :: Proxy a -> Proxy (One a)-pOne _ = Proxy---- | construct Many proxy. since 0.5.1.0.-pMany :: Proxy a -> Proxy (Many a)-pMany _ = Proxy---- | construct Some proxy. since 0.5.1.0.-pSome :: Proxy a -> Proxy (Some a)-pSome _ = Proxy---- | construct Check proxy. since 0.5.1.0.-pCheck :: Proxy a -> Proxy (Check a)-pCheck _ = Proxy
+ src/Control/Monad/Apiary/Filter/Internal/Strategy.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts #-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoMonomorphismRestriction #-}++module Control.Monad.Apiary.Filter.Internal.Strategy where++import Data.Apiary.SList++import Data.Maybe+import Data.Proxy+import Data.Reflection++class Strategy (w :: * -> *) where+  type SNext w (as :: [*]) a  :: [*]+  readStrategy :: (v -> Maybe a)+               -> ((k,v) -> Bool)+               -> Proxy (w a)+               -> [(k, v)]+               -> SList as +               -> Maybe (SList (SNext w as a))++getQuery :: (v -> Maybe a) -> Proxy (w a) -> ((k,v) -> Bool) -> [(k, v)] -> [Maybe a]+getQuery readf _ kf = map readf . map snd . filter kf+++-- | get first matched key( [1,) params to Type.). since 0.5.0.0.+data Option a+instance Strategy Option where+    type SNext Option as a = Snoc as (Maybe a)+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else Just . sSnoc l $ case catMaybes rs of+               []  -> Nothing+               a:_ -> Just a++-- | get first matched key ( [0,) params to Maybe Type.) since 0.5.0.0.+data First a+instance Strategy First where+    type SNext First as a = Snoc as a+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else case catMaybes rs of+               [] -> Nothing+               a:_ -> Just $ sSnoc l a++-- | get key ( [1] param to Type.) since 0.5.0.0.+data One a+instance Strategy One where+    type SNext One as a = Snoc as a+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else case catMaybes rs of+               [a] -> Just $ sSnoc l a+               _   -> Nothing++-- | get parameters ( [0,) params to [Type] ) since 0.5.0.0.+data Many a+instance Strategy Many where+    type SNext Many as a = Snoc as [a]+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else Just $ sSnoc l (catMaybes rs)++-- | get parameters ( [1,) params to [Type] ) since 0.5.0.0.+data Some a+instance Strategy Some where+    type SNext Some as a = Snoc as [a]+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else case catMaybes rs of+               [] -> Nothing+               as -> Just $ sSnoc l as++-- | get parameters with upper limit ( [1,n] to [Type]) since 0.6.0.0.+data LimitSome u a+instance (Reifies u Int) => Strategy (LimitSome u) where+    type SNext (LimitSome u) as a = Snoc as [a]+    readStrategy rf k p q l =+        let rs = take (reflectLimit p) $ getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else case catMaybes rs of+               [] -> Nothing+               as -> Just $ sSnoc l as++reflectLimit :: Reifies n Int => Proxy (LimitSome n a) -> Int+reflectLimit p = reflect $ asTyInt p+  where+    asTyInt :: Proxy (LimitSome u a) -> Proxy u+    asTyInt _ = Proxy++-- | type check ( [0,) params to No argument ) since 0.5.0.0.+data Check a+instance Strategy Check where+    type SNext Check as a = as+    readStrategy rf k p q l =+        let rs = getQuery rf p k q+        in if any isNothing rs+           then Nothing+           else case  catMaybes rs of+               [] -> Nothing+               _  -> Just l++-- | construct Option proxy. since 0.5.1.0.+pOption :: Proxy a -> Proxy (Option a)+pOption _ = Proxy++-- | construct First proxy. since 0.5.1.0.+pFirst :: Proxy a -> Proxy (First a)+pFirst _ = Proxy++-- | construct One proxy. since 0.5.1.0.+pOne :: Proxy a -> Proxy (One a)+pOne _ = Proxy++-- | construct Many proxy. since 0.5.1.0.+pMany :: Proxy a -> Proxy (Many a)+pMany _ = Proxy++-- | construct Some proxy. since 0.5.1.0.+pSome :: Proxy a -> Proxy (Some a)+pSome _ = Proxy++-- | construct Check proxy. since 0.5.1.0.+pCheck :: Proxy a -> Proxy (Check a)+pCheck _ = Proxy
src/Control/Monad/Apiary/Internal.hs view
@@ -78,7 +78,7 @@         unApiaryT m run (\r -> grd r >>= \c -> g r c) cfg cont  action :: Monad m => Fn c (ActionT m ()) -> ApiaryT c m ()-action = actionWithPreAction_ (return ())+action = actionWithPreAction (const $ return ())  -- | execute action before main action. since v0.4.2.0 actionWithPreAction :: Monad m => (SList xs -> ActionT IO a)@@ -87,19 +87,3 @@     tr  <- getRunner     grd <- getGuard     addRoute $ filterToActionT grd >>= \c -> (pa c) >> tr (apply a c)----- | execute no argument action before main action. since v0.4.2.0-actionWithPreAction_ :: Monad m => ActionT IO a-                     -> Fn c (ActionT m ()) -> ApiaryT c m ()-actionWithPreAction_ pa a = do-    tr  <- getRunner-    grd <- getGuard-    addRoute $ filterToActionT grd >>= \c -> pa >> tr (apply a c)--{-# DEPRECATED action_ "use action method." #-}-action_ :: Monad m => ActionT m () -> ApiaryT c m ()-action_ a = do-    tr <- getRunner-    grd <- getGuard-    addRoute $ filterToActionT grd >> tr a
src/Data/Apiary/Param.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE TypeFamilies #-}@@ -19,7 +20,14 @@ import Data.Int import Data.Word import Data.Proxy+import Data.String(IsString) +jsToBool :: (IsString a, Eq a) => a -> Bool+jsToBool = flip notElem jsFalse+    where+      jsFalse = ["false", "0", "-0", "", "null", "undefined", "NaN"]++ class Path a where   readPath :: T.Text -> Maybe a @@ -27,6 +35,10 @@     readPath    s | T.null s  = Nothing                   | otherwise = Just $ T.head s +-- | javascript boolean.+-- when \"false\", \"0\", \"-0\", \"\", \"null\", \"undefined\", \"NaN\" then False, else True. since 0.6.0.0.+instance Path Bool where readPath = Just . jsToBool+ instance Path Int     where readPath    = readMaybe . T.unpack instance Path Int8    where readPath    = readMaybe . T.unpack instance Path Int16   where readPath    = readMaybe . T.unpack@@ -54,6 +66,10 @@ class Query a where     readQuery :: Maybe S.ByteString -> Maybe a +-- | javascript boolean.+-- when \"false\", \"0\", \"-0\", \"\", \"null\", \"undefined\", \"NaN\" then False, else True. since 0.6.0.0.+instance Query Bool where readQuery = fmap jsToBool+ instance Query Int     where readQuery = maybe Nothing (readMaybe . S.unpack) instance Query Int8    where readQuery = maybe Nothing (readMaybe . S.unpack) instance Query Int16   where readQuery = maybe Nothing (readMaybe . S.unpack)@@ -85,9 +101,11 @@ instance Query () where     readQuery _ = Just () +pBool :: Proxy Bool+pBool = Proxy+ pInt :: Proxy Int pInt = Proxy- pInt8 :: Proxy Int8 pInt8 = Proxy pInt16 :: Proxy Int16@@ -103,6 +121,8 @@ pWord = Proxy pWord8 :: Proxy Word8 pWord8 = Proxy+pWord16 :: Proxy Word16+pWord16 = Proxy pWord32 :: Proxy Word32 pWord32 = Proxy pWord64 :: Proxy Word64
src/Web/Apiary.hs view
@@ -4,6 +4,7 @@     , module Control.Monad.Apiary.Action     , module Control.Monad.Apiary.Filter     , module Data.Apiary.Param+    , act     -- * reexports     -- | MonadIO     , module Control.Monad.Trans@@ -18,3 +19,4 @@ import Control.Monad.Trans(MonadIO(..)) import Control.Monad (MonadPlus(..), msum, mfilter, guard) import Control.Monad.Apiary.Filter+import Web.Apiary.TH
+ src/Web/Apiary/TH.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TemplateHaskell #-}+module Web.Apiary.TH where++import Control.Monad.Apiary+import Control.Monad.Apiary.Action+import Network.HTTP.Types.Status+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import qualified Data.Text as T+import qualified Data.ByteString.Char8 as S+import Network.Mime++numToCode :: Int -> ExpQ+numToCode = \case+    100 -> varE 'status100+    101 -> varE 'status101+    200 -> varE 'status200+    201 -> varE 'status201+    n   -> fail $ "unknown HTTP status code:" ++ show n++-- | shortcut action. since 0.6.0.0.+--+-- @+-- [act|200 .html|] == [act|200 text/html|] ==+-- action $ \\arguments -> do+--     status 200+--     contentType "text/html"+-- @+act :: QuasiQuoter+act = QuasiQuoter +    { quoteExp  = act'+    , quotePat  = \_ -> fail "act QQ only Exp."+    , quoteType = \_ -> fail "act QQ only Exp."+    , quoteDec  = \_ -> fail "act QQ only Exp."+    }++parseAct :: String -> (Int, String)+parseAct s =+    let (code, ct) = T.break (== ' ') . T.strip $ T.pack s+        mime       = case T.strip ct of+            t | T.head t == '.' -> defaultMimeLookup t+              | otherwise       -> S.pack $ T.unpack t+    in (read $ T.unpack code, S.unpack mime)++act' :: String -> ExpQ+act' s = +    let (code, mime) = parseAct s+         in [| actionWithPreAction (\_ -> do +             status $(numToCode code)+             contentType $(stringE mime)+             )|]