X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResource%2FDispatcher.hs;h=029d7b2de6294fb0bc970ae7b951d51932049a3f;hp=13080ee1da3a0e9fe32bca44152e6375cb774a58;hb=b22e702f8161447a460847c6e6c97104c150534f;hpb=6cc54ccef706a0eba367e63c8b4248df81010f2a diff --git a/Network/HTTP/Lucu/Resource/Dispatcher.hs b/Network/HTTP/Lucu/Resource/Dispatcher.hs index 13080ee..029d7b2 100644 --- a/Network/HTTP/Lucu/Resource/Dispatcher.hs +++ b/Network/HTTP/Lucu/Resource/Dispatcher.hs @@ -1,77 +1,83 @@ {-# LANGUAGE ExistentialQuantification , FlexibleInstances + , MultiParamTypeClasses + , UndecidableInstances , UnicodeSyntax #-} -- |FIXME: doc module Network.HTTP.Lucu.Resource.Dispatcher ( Dispatchable(..) , Dispatcher + , uriHost + , uriPathSegments ) where -import Control.Applicative -import Data.ByteString (ByteString) import Data.CaseInsensitive (CI) +import Data.Collections import Data.Monoid import Data.Text (Text) import Network.HTTP.Lucu.Resource.Internal +import Network.HTTP.Lucu.Utils +import Network.URI import Prelude.Unicode -- |FIXME: docs +-- +-- Minimal complete definition: 'dispatch' class Dispatchable α where - dispatch ∷ α - → CI Text - → [ByteString] - → IO (Maybe ([ByteString], ResourceDef)) + dispatch ∷ α → URI → IO (Maybe Resource) dispatcher ∷ α → Dispatcher {-# INLINE dispatcher #-} dispatcher = Dispatcher --- |FIXME: doc +-- |Container type for 'Dispatchable' type class. data Dispatcher = ∀α. Dispatchable α ⇒ Dispatcher α instance Dispatchable Dispatcher where dispatch (Dispatcher α) = dispatch α dispatcher = id --- |FIXME: doc +-- |@insert a b@ first tries @a@, and then tries @b@. @insertMany bs +-- a@ first tries @a@, and then tries each one in @bs@ from head to +-- tail. +instance Dispatchable α ⇒ Unfoldable Dispatcher α where + {-# INLINEABLE insert #-} + insert a (Dispatcher b) + = dispatcher + $ \uri → do r ← dispatch a uri + case r of + Just _ → return r + Nothing → dispatch b uri + {-# INLINE empty #-} + empty = dispatcher e + where + e ∷ URI → IO (Maybe Resource) + {-# INLINE e #-} + e = return ∘ const Nothing + {-# INLINE singleton #-} + singleton = dispatcher + +-- |@a `'mappend'` b@ first tries @a@, and then tries @b@. instance Monoid Dispatcher where {-# INLINE mempty #-} - mempty = dispatcher () - - {-# INLINEABLE mappend #-} - mappend (Dispatcher α) (Dispatcher β) - = dispatcher - $ \host path → do r ← dispatch α host path - case r of - Just _ → return r - Nothing → dispatch β host path + mempty = empty + {-# INLINE mappend #-} + mappend = insert -instance Dispatchable (CI Text - → [ByteString] - → IO (Maybe ([ByteString], ResourceDef))) where +-- |An IO-based dispatcher. +instance Dispatchable (URI → IO (Maybe Resource)) where dispatch = id -instance Dispatchable (CI Text → [ByteString] → IO (Maybe ResourceDef)) where - dispatch = ((((<$>) ∘ (<$>)) ((,) []) ∘) ∘) +-- |A pure dispatcher. +instance Dispatchable (URI → Maybe Resource) where + dispatch = (return ∘) -instance Dispatchable (CI Text → [ByteString] → Maybe ResourceDef) where - dispatch = (((return ∘ ((,) [] <$>)) ∘) ∘) +-- |The constant dispatcher returning always the same 'Resource'. +instance Dispatchable Resource where + dispatch = const ∘ return ∘ Just -instance Dispatchable ([ByteString] → IO (Maybe ResourceDef)) where - dispatch = const ∘ (((<$>) ∘ (<$>)) ((,) []) ∘) - -instance Dispatchable ([ByteString] → Maybe ResourceDef) where - dispatch = const ∘ ((return ∘ ((,) [] <$>)) ∘) - -instance Dispatchable (IO (Maybe ResourceDef)) where - dispatch = const ∘ const ∘ ((<$>) ∘ (<$>)) ((,) []) - --- |The constant dispatcher returning always the same 'ResourceDef'. -instance Dispatchable ResourceDef where - dispatch = const ∘ const ∘ return ∘ Just ∘ (,) [] - --- |The empty dispatcher returning always 'Nothing'. -instance Dispatchable () where - dispatch _ _ _ = return Nothing \ No newline at end of file +-- |FIXME: doc +uriHost ∷ URI → CI Text +uriHost = error "FIXME"