@@ -0,0 +1,611 @@
1+-- Hoogle documentation, generated by Haddock
2+-- See Hoogle, http://www.haskell.org/hoogle/
8+module Servant.Common.Text
10+-- | For getting values from url captures and query string parameters
12+fromText :: FromText a => Text -> Maybe a
14+-- | For putting values in paths and query string parameters
16+toText :: ToText a => a -> Text
18+instance FromText Float
19+instance ToText Double
20+instance FromText Double
21+instance ToText Integer
22+instance FromText Integer
23+instance ToText Word64
24+instance FromText Word64
25+instance ToText Word32
26+instance FromText Word32
27+instance ToText Word16
28+instance FromText Word16
30+instance FromText Word8
32+instance FromText Word
34+instance FromText Int64
36+instance FromText Int32
38+instance FromText Int16
40+instance FromText Int8
44+instance FromText Bool
45+instance ToText String
46+instance FromText String
48+instance FromText Text
51+-- | This module lets you implement <a>Server</a>s for defined APIs. You'll
52+-- most likely just need <a>serve</a>.
55+-- | <a>serve</a> allows you to implement an API and produce a wai
56+-- <a>Application</a>.
61+-- type MyApi = "books" :> Get [Book] -- GET /books
62+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
64+-- server :: Server MyApi
65+-- server = listAllBooks :<|> postBook
66+-- where listAllBooks = ...
67+-- postBook book = ...
70+-- app = serve myApi server
73+-- main = Network.Wai.Handler.Warp.run 8080 app
75+serve :: HasServer layout => Proxy layout -> Server layout -> Application
76+toApplication :: RoutingApplication -> Application
79+-- | the usual "not found" error
80+NotFound :: RouteMismatch
82+-- | a more informative "you just got the HTTP method wrong" error
83+WrongMethod :: RouteMismatch
85+-- | an even more informative "your json request body wasn't valid" error
86+InvalidBody :: RouteMismatch
89+-- > mempty = NotFound
91+-- > NotFound <a>mappend</a> x = x
92+-- > WrongMethod <a>mappend</a> InvalidBody = InvalidBody
93+-- > WrongMethod <a>mappend</a> _ = WrongMethod
94+-- > InvalidBody <a>mappend</a> _ = InvalidBody
97+-- | A wrapper around <tt><a>Either</a> <a>RouteMismatch</a> a</tt>.
99+RR :: Either RouteMismatch a -> RouteResult a
100+routeResult :: RouteResult a -> Either RouteMismatch a
101+failWith :: RouteMismatch -> RouteResult a
102+succeedWith :: a -> RouteResult a
103+isMismatch :: RouteResult a -> Bool
105+-- | If we get a <a>Right</a>, it has precedence over everything else.
107+-- This in particular means that if we could get several <a>Right</a>s,
108+-- only the first we encounter would be taken into account.
109+type RoutingApplication = Request -> (RouteResult Response -> IO ResponseReceived) -> IO ResponseReceived
110+class HasServer layout where type family Server layout :: *
111+route :: HasServer layout => Proxy layout -> Server layout -> RoutingApplication
112+instance Eq RouteMismatch
113+instance Show RouteMismatch
114+instance Eq a => Eq (RouteResult a)
115+instance Show a => Show (RouteResult a)
116+instance Monoid (RouteResult a)
117+instance Monoid RouteMismatch
119+module Servant.API.Sub
121+-- | The contained API (second argument) can be found under <tt>("/" ++
122+-- path)</tt> (path being the first argument).
127+-- -- GET /hello/world
128+-- -- returning a JSON encoded World value
129+-- type MyApi = "hello" :> "world" :> Get World
131+data (:>) (path :: k) a
132+(:>) :: Proxy path -> a -> (:>) a
134+-- | Make sure the incoming request starts with <tt>"/path"</tt>, strip it
135+-- and pass the rest of the request path to <tt>sublayout</tt>.
136+instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout)
138+module Servant.API.Alternative
140+-- | Union of two APIs, first takes precedence in case of overlap.
145+-- type MyApi = "books" :> Get [Book] -- GET /books
146+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
149+(:<|>) :: a -> b -> (:<|>) a b
151+-- | A server for <tt>a <a>:<|></a> b</tt> first tries to match the
152+-- request again the route represented by <tt>a</tt> and if it fails
153+-- tries <tt>b</tt>. You must provide a request handler for each route.
156+-- type MyApi = "books" :> Get [Book] -- GET /books
157+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
159+-- server :: Server MyApi
160+-- server = listAllBooks :<|> postBook
161+-- where listAllBooks = ...
162+-- postBook book = ...
164+instance (HasServer a, HasServer b) => HasServer (a :<|> b)
166+module Servant.API.Capture
168+-- | Capture a value from the request path under a certain type <tt>a</tt>.
173+-- -- GET /books/:isbn
174+-- type MyApi = "books" :> Capture "isbn" Text :> Get Book
177+instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout)
179+module Servant.API.QueryParam
181+-- | Lookup the value associated to the <tt>sym</tt> query string parameter
182+-- and try to extract it as a value of type <tt>a</tt>.
187+-- -- /books?author=<author name>
188+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
190+data QueryParam sym a
192+-- | If you use <tt><a>QueryParam</a> "author" Text</tt> in one of the
193+-- endpoints for your API, this automatically requires your server-side
194+-- handler to be a function that takes an argument of type
195+-- <tt><a>Maybe</a> <tt>Text</tt></tt>.
197+-- This lets servant worry about looking it up in the query string and
198+-- turning it into a value of the type you specify, enclosed in
199+-- <a>Maybe</a>, because it may not be there and servant would then hand
200+-- you <a>Nothing</a>.
202+-- You can control how it'll be converted from <tt>Text</tt> to your type
203+-- by simply providing an instance of <a>FromText</a> for your type.
208+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
210+-- server :: Server MyApi
211+-- server = getBooksBy
212+-- where getBooksBy :: Maybe Text -> EitherT (Int, String) IO [Book]
213+-- getBooksBy Nothing = ...return all books...
214+-- getBooksBy (Just author) = ...return books by the given author...
217+-- | Lookup the values associated to the <tt>sym</tt> query string
218+-- parameter and try to extract it as a value of type <tt>[a]</tt>. This
219+-- is typically meant to support query string parameters of the form
220+-- <tt>param[]=val1&param[]=val2</tt> and so on. Note that servant
221+-- doesn't actually require the <tt>[]</tt>s and will fetch the values
222+-- just fine with <tt>param=val1&param=val2</tt>, too.
227+-- -- /books?authors[]=<author1>&authors[]=<author2>&...
228+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
230+data QueryParams sym a
232+-- | If you use <tt><a>QueryParams</a> "authors" Text</tt> in one of the
233+-- endpoints for your API, this automatically requires your server-side
234+-- handler to be a function that takes an argument of type
235+-- <tt>[<tt>Text</tt>]</tt>.
237+-- This lets servant worry about looking up 0 or more values in the query
238+-- string associated to <tt>authors</tt> and turning each of them into a
239+-- value of the type you specify.
241+-- You can control how the individual values are converted from
242+-- <tt>Text</tt> to your type by simply providing an instance of
243+-- <a>FromText</a> for your type.
248+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
250+-- server :: Server MyApi
251+-- server = getBooksBy
252+-- where getBooksBy :: [Text] -> EitherT (Int, String) IO [Book]
253+-- getBooksBy authors = ...return all books by these authors...
256+-- | Lookup a potentially value-less query string parameter with boolean
257+-- semantics. If the param <tt>sym</tt> is there without any value, or if
258+-- it's there with value "true" or "1", it's interpreted as <a>True</a>.
259+-- Otherwise, it's interpreted as <a>False</a>.
264+-- -- /books?published
265+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
269+-- | If you use <tt><a>QueryFlag</a> "published"</tt> in one of the
270+-- endpoints for your API, this automatically requires your server-side
271+-- handler to be a function that takes an argument of type <a>Bool</a>.
276+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
278+-- server :: Server MyApi
280+-- where getBooks :: Bool -> EitherT (Int, String) IO [Book]
281+-- getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...
283+instance (KnownSymbol sym, HasServer sublayout) => HasServer (QueryFlag sym :> sublayout)
284+instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParams sym a :> sublayout)
285+instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParam sym a :> sublayout)
287+module Servant.API.ReqBody
289+-- | Extract the request body as a value of type <tt>a</tt>.
295+-- type MyApi = "books" :> ReqBody Book :> Post Book
299+-- | If you use <a>ReqBody</a> in one of the endpoints for your API, this
300+-- automatically requires your server-side handler to be a function that
301+-- takes an argument of the type specified by <a>ReqBody</a>. This lets
302+-- servant worry about extracting it from the request and turning it into
303+-- a value of the type you specify.
305+-- All it asks is for a <a>FromJSON</a> instance.
310+-- type MyApi = "books" :> ReqBody Book :> Post Book
312+-- server :: Server MyApi
314+-- where postBook :: Book -> EitherT (Int, String) IO Book
315+-- postBook book = ...insert into your db...
317+instance (FromJSON a, HasServer sublayout) => HasServer (ReqBody a :> sublayout)
319+module Servant.API.Get
321+-- | Endpoint for simple GET requests. Serves the result as JSON.
326+-- type MyApi = "books" :> Get [Book]
330+-- | When implementing the handler for a <a>Get</a> endpoint, just like for
331+-- <a>Delete</a>, <a>Post</a> and <a>Put</a>, the handler code runs in
332+-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
333+-- represents the status code and the <a>String</a> a message, returned
334+-- in case of failure. You can quite handily use <a>left</a> to quickly
335+-- fail if some conditions are not met.
337+-- If successfully returning a value, we just require that its type has a
338+-- <a>ToJSON</a> instance and servant takes care of encoding it for you,
339+-- yielding status code 200 along the way.
340+instance Typeable Get
341+instance ToJSON result => HasServer (Get result)
343+module Servant.API.Post
345+-- | Endpoint for POST requests. The type variable represents the type of
346+-- the response body (not the request body, use <a>RQBody</a> for that).
352+-- -- with a JSON encoded Book as the request body
353+-- -- returning the just-created Book
354+-- type MyApi = "books" :> ReqBody Book :> Post Book
358+-- | When implementing the handler for a <a>Post</a> endpoint, just like
359+-- for <a>Delete</a>, <a>Get</a> and <a>Put</a>, the handler code runs in
360+-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
361+-- represents the status code and the <a>String</a> a message, returned
362+-- in case of failure. You can quite handily use <a>left</a> to quickly
363+-- fail if some conditions are not met.
365+-- If successfully returning a value, we just require that its type has a
366+-- <a>ToJSON</a> instance and servant takes care of encoding it for you,
367+-- yielding status code 201 along the way.
368+instance Typeable Post
369+instance ToJSON a => HasServer (Post a)
371+module Servant.API.Delete
373+-- | Combinator for DELETE requests.
378+-- -- DELETE /books/:isbn
379+-- type MyApi = "books" :> Capture "isbn" Text :> Delete
383+-- | If you have a <a>Delete</a> endpoint in your API, the handler for this
384+-- endpoint is meant to delete a resource.
386+-- The code of the handler will, just like for <a>Get</a>, <a>Post</a>
387+-- and <a>Put</a>, run in <tt>EitherT (Int, String) IO ()</tt>. The
388+-- <a>Int</a> represents the status code and the <a>String</a> a message
389+-- to be returned. You can use <a>left</a> to painlessly error out if the
390+-- conditions for a successful deletion are not met.
391+instance Typeable Delete
392+instance HasServer Delete
394+module Servant.API.Put
396+-- | Endpoint for PUT requests, usually used to update a ressource. The
397+-- type <tt>a</tt> is the type of the response body that's returned.
402+-- -- PUT /books/:isbn
403+-- -- with a Book as request body, returning the updated Book
404+-- type MyApi = "books" :> Capture "isbn" Text :> ReqBody Book :> Put Book
408+-- | When implementing the handler for a <a>Put</a> endpoint, just like for
409+-- <a>Delete</a>, <a>Get</a> and <a>Post</a>, the handler code runs in
410+-- the <tt>EitherT (Int, String) IO</tt> monad, where the <a>Int</a>
411+-- represents the status code and the <a>String</a> a message, returned
412+-- in case of failure. You can quite handily use <a>left</a> to quickly
413+-- fail if some conditions are not met.
415+-- If successfully returning a value, we just require that its type has a
416+-- <a>ToJSON</a> instance and servant takes care of encoding it for you,
417+-- yielding status code 200 along the way.
418+instance Typeable Put
419+instance ToJSON a => HasServer (Put a)
422+-- | QuasiQuoting utilities for API types.
424+-- <a>sitemap</a> allows you to write your type in a very natural way:
428+-- PUT hello String -> ()
429+-- POST hello/p:Int String -> ()
430+-- GET hello/?name:String Int
437+-- "hello" :> ReqBody String :> Put ()
438+-- :<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()
439+-- :<|> "hello" :> QueryParam "name" String :> Get Int
442+-- Note the <tt>/</tt> before a <tt>QueryParam</tt>!
445+-- | Finally-tagless encoding for our DSL. Keeping <tt>repr'</tt> and
446+-- <tt>repr</tt> distinct when writing functions with an <tt>ExpSYM</tt>
447+-- context ensures certain invariants (for instance, that there is only
448+-- one of <a>get</a>, <a>post</a>, <a>put</a>, and <a>delete</a> in a
449+-- value), but sometimes requires a little more work.
450+class ExpSYM repr' repr | repr -> repr', repr' -> repr
451+lit :: ExpSYM repr' repr => String -> repr' -> repr
452+capture :: ExpSYM repr' repr => String -> String -> repr -> repr
453+reqBody :: ExpSYM repr' repr => String -> repr -> repr
454+queryParam :: ExpSYM repr' repr => String -> String -> repr -> repr
455+conj :: ExpSYM repr' repr => repr' -> repr -> repr
456+get :: ExpSYM repr' repr => String -> repr
457+post :: ExpSYM repr' repr => String -> repr
458+put :: ExpSYM repr' repr => String -> repr
459+delete :: ExpSYM repr' repr => String -> repr
460+(>:) :: Type -> Type -> Type
461+parseMethod :: ExpSYM repr' repr => Parser (String -> repr)
462+parseUrlSegment :: ExpSYM repr repr => Parser (repr -> repr)
463+parseUrl :: ExpSYM repr repr => Parser (repr -> repr)
466+ReqArgVal :: String -> String -> Typ
467+parseTyp :: Parser Typ
468+parseEntry :: ExpSYM repr repr => Parser repr
469+blockComment :: Parser ()
470+inlineComment :: Parser ()
473+parseAll :: Parser Type
475+-- | The sitemap QuasiQuoter.
478+-- <li><tt>...<i><a>var</a>:<a>type</a></i>...</tt> becomes a
480+-- <li><tt>.../?<a>var</a>:<a>type</a></tt> becomes a query
482+-- <li><tt><a>method</a> ... <a>typ</a></tt> becomes a method returning
483+-- <tt><a>typ</a></tt></li>
484+-- <li><tt><a>method</a> ... <a>typ1</a> -> <a>typ2</a></tt> becomes a
485+-- method with request body of <tt><a>typ1</a></tt> and returning
486+-- <tt><a>typ2</a></tt></li>
489+-- Comments are allowed, and have the standard Haskell format
492+-- <li><tt>--</tt> for inline</li>
493+-- <li><tt>{- ... -}</tt> for block</li>
495+sitemap :: QuasiQuoter
496+instance ExpSYM Type Type
499+-- | Type safe internal links.
501+-- Provides the function <a>mkLink</a>:
504+-- type API = Proxy ("hello" :> Get Int
505+-- :<a>|</a> "bye" :> QueryParam "name" String :> Post Bool)
510+-- link1 :: Proxy ("hello" :> Get Int)
513+-- link2 :: Proxy ("hello" :> Delete)
516+-- mkLink link1 API -- typechecks, returns 'Link "/hello"'
518+-- mkLink link2 API -- doesn't typecheck
521+-- That is, <a>mkLink</a> takes two arguments, a link proxy and a
522+-- sitemap, and returns a <a>Link</a>, but only typechecks if the link
523+-- proxy is a valid link, and part of the sitemap.
525+-- <b>N.B.:</b> <a>mkLink</a> assumes a capture matches any string
526+-- (without slashes).
527+module Servant.Utils.Links
529+-- | The 'ValidLinkIn f s' constraint holds when <tt>s</tt> is an API that
530+-- contains <tt>f</tt>, and <tt>f</tt> is a link.
531+class ValidLinkIn f s
532+mkLink :: ValidLinkIn f s => f -> s -> Link
534+Link :: String -> Link
536+vlh :: VLinkHelper f => proxy f -> String
538+instance VLinkHelper (Post x)
539+instance VLinkHelper (Get x)
540+instance (KnownSymbol s, VLinkHelper e) => VLinkHelper (s :> e)
541+instance (IsElem f s ~ 'True, IsLink f ~ 'True, VLinkHelper f) => ValidLinkIn f s
543+module Servant.API.Raw
545+-- | Endpoint for plugging in your own Wai <a>Application</a>s.
547+-- The given <a>Application</a> will get the request as received by the
548+-- server, potentially with a modified (stripped) <a>pathInfo</a> if the
549+-- <a>Application</a> is being routed with <a>:></a>.
551+-- In addition to just letting you plug in your existing WAI
552+-- <a>Application</a>s, this can also be used with <a>serveDirectory</a>
553+-- to serve static files stored in a particular directory on your
554+-- filesystem, or to serve your API's documentation with
555+-- <a>serveDocumentation</a>.
558+-- | Just pass the request to the underlying application and serve its
564+-- type MyApi = "images" :> Raw
566+-- server :: Server MyApi
567+-- server = serveDirectory "/var/www/images"
569+instance HasServer Raw
572+-- | This module defines a sever-side handler that lets you serve static
576+-- <li><a>serveDirectory</a> lets you serve anything that lives under a
577+-- particular directory on your filesystem.</li>
579+module Servant.Utils.StaticFiles
581+-- | Serve anything under the specified directory as a <a>Raw</a> endpoint.
584+-- type MyApi = "static" :> Raw
586+-- server :: Server MyApi
587+-- server = serveDirectory "/var/www"
590+-- would capture any request to <tt>/static/<something></tt> and
591+-- look for <tt><something></tt> under <tt>/var/www</tt>.
593+-- It will do its best to guess the MIME type for that file, based on the
594+-- extension, and send an appropriate <i>Content-Type</i> header if
597+-- If your goal is to serve HTML, CSS and Javascript files that use the
598+-- rest of the API as a webapp backend, you will most likely not want the
599+-- static files to be hidden behind a <i>/static/</i> prefix. In that
600+-- case, remember to put the <a>serveDirectory</a> handler in the last
601+-- position, because <i>servant</i> will try to match the handlers in
603+serveDirectory :: FilePath -> Server Raw
609+-- | A concrete, poly-kinded proxy type
610+data Proxy (t :: k) :: k -> *