@@ -0,0 +1,611 @@
1+-- Hoogle documentation, generated by Haddock
2+-- See Hoogle, http://www.haskell.org/hoogle/
3+
4+
5+@package servant
6+@version 0.2
7+
8+module Servant.Common.Text
9+
10+-- | For getting values from url captures and query string parameters
11+class FromText a
12+fromText :: FromText a => Text -> Maybe a
13+
14+-- | For putting values in paths and query string parameters
15+class ToText a
16+toText :: ToText a => a -> Text
17+instance ToText Float
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
29+instance ToText Word8
30+instance FromText Word8
31+instance ToText Word
32+instance FromText Word
33+instance ToText Int64
34+instance FromText Int64
35+instance ToText Int32
36+instance FromText Int32
37+instance ToText Int16
38+instance FromText Int16
39+instance ToText Int8
40+instance FromText Int8
41+instance ToText Int
42+instance FromText Int
43+instance ToText Bool
44+instance FromText Bool
45+instance ToText String
46+instance FromText String
47+instance ToText Text
48+instance FromText Text
49+
50+
51+-- | This module lets you implement <a>Server</a>s for defined APIs. You'll
52+-- most likely just need <a>serve</a>.
53+module Servant.Server
54+
55+-- | <a>serve</a> allows you to implement an API and produce a wai
56+-- <a>Application</a>.
57+--
58+-- Example:
59+--
60+-- <pre>
61+-- type MyApi = "books" :> Get [Book] -- GET /books
62+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
63+--
64+-- server :: Server MyApi
65+-- server = listAllBooks :<|> postBook
66+-- where listAllBooks = ...
67+-- postBook book = ...
68+--
69+-- app :: Application
70+-- app = serve myApi server
71+--
72+-- main :: IO ()
73+-- main = Network.Wai.Handler.Warp.run 8080 app
74+-- </pre>
75+serve :: HasServer layout => Proxy layout -> Server layout -> Application
76+toApplication :: RoutingApplication -> Application
77+data RouteMismatch
78+
79+-- | the usual "not found" error
80+NotFound :: RouteMismatch
81+
82+-- | a more informative "you just got the HTTP method wrong" error
83+WrongMethod :: RouteMismatch
84+
85+-- | an even more informative "your json request body wasn't valid" error
86+InvalidBody :: RouteMismatch
87+
88+-- | <pre>
89+-- > mempty = NotFound
90+-- >
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
95+-- </pre>
96+
97+-- | A wrapper around <tt><a>Either</a> <a>RouteMismatch</a> a</tt>.
98+newtype RouteResult a
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
104+
105+-- | If we get a <a>Right</a>, it has precedence over everything else.
106+--
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
118+
119+module Servant.API.Sub
120+
121+-- | The contained API (second argument) can be found under <tt>("/" ++
122+-- path)</tt> (path being the first argument).
123+--
124+-- Example:
125+--
126+-- <pre>
127+-- -- GET /hello/world
128+-- -- returning a JSON encoded World value
129+-- type MyApi = "hello" :> "world" :> Get World
130+-- </pre>
131+data (:>) (path :: k) a
132+(:>) :: Proxy path -> a -> (:>) a
133+
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)
137+
138+module Servant.API.Alternative
139+
140+-- | Union of two APIs, first takes precedence in case of overlap.
141+--
142+-- Example:
143+--
144+-- <pre>
145+-- type MyApi = "books" :> Get [Book] -- GET /books
146+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
147+-- </pre>
148+data (:<|>) a b
149+(:<|>) :: a -> b -> (:<|>) a b
150+
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.
154+--
155+-- <pre>
156+-- type MyApi = "books" :> Get [Book] -- GET /books
157+-- :<|> "books" :> ReqBody Book :> Post Book -- POST /books
158+--
159+-- server :: Server MyApi
160+-- server = listAllBooks :<|> postBook
161+-- where listAllBooks = ...
162+-- postBook book = ...
163+-- </pre>
164+instance (HasServer a, HasServer b) => HasServer (a :<|> b)
165+
166+module Servant.API.Capture
167+
168+-- | Capture a value from the request path under a certain type <tt>a</tt>.
169+--
170+-- Example:
171+--
172+-- <pre>
173+-- -- GET /books/:isbn
174+-- type MyApi = "books" :> Capture "isbn" Text :> Get Book
175+-- </pre>
176+data Capture sym a
177+instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout)
178+
179+module Servant.API.QueryParam
180+
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>.
183+--
184+-- Example:
185+--
186+-- <pre>
187+-- -- /books?author=<author name>
188+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
189+-- </pre>
190+data QueryParam sym a
191+
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>.
196+--
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>.
201+--
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.
204+--
205+-- Example:
206+--
207+-- <pre>
208+-- type MyApi = "books" :> QueryParam "author" Text :> Get [Book]
209+--
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...
215+-- </pre>
216+
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.
223+--
224+-- Example:
225+--
226+-- <pre>
227+-- -- /books?authors[]=<author1>&authors[]=<author2>&...
228+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
229+-- </pre>
230+data QueryParams sym a
231+
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>.
236+--
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.
240+--
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.
244+--
245+-- Example:
246+--
247+-- <pre>
248+-- type MyApi = "books" :> QueryParams "authors" Text :> Get [Book]
249+--
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...
254+-- </pre>
255+
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>.
260+--
261+-- Example:
262+--
263+-- <pre>
264+-- -- /books?published
265+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
266+-- </pre>
267+data QueryFlag sym
268+
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>.
272+--
273+-- Example:
274+--
275+-- <pre>
276+-- type MyApi = "books" :> QueryFlag "published" :> Get [Book]
277+--
278+-- server :: Server MyApi
279+-- server = getBooks
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...
282+-- </pre>
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)
286+
287+module Servant.API.ReqBody
288+
289+-- | Extract the request body as a value of type <tt>a</tt>.
290+--
291+-- Example:
292+--
293+-- <pre>
294+-- -- POST /books
295+-- type MyApi = "books" :> ReqBody Book :> Post Book
296+-- </pre>
297+data ReqBody a
298+
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.
304+--
305+-- All it asks is for a <a>FromJSON</a> instance.
306+--
307+-- Example:
308+--
309+-- <pre>
310+-- type MyApi = "books" :> ReqBody Book :> Post Book
311+--
312+-- server :: Server MyApi
313+-- server = postBook
314+-- where postBook :: Book -> EitherT (Int, String) IO Book
315+-- postBook book = ...insert into your db...
316+-- </pre>
317+instance (FromJSON a, HasServer sublayout) => HasServer (ReqBody a :> sublayout)
318+
319+module Servant.API.Get
320+
321+-- | Endpoint for simple GET requests. Serves the result as JSON.
322+--
323+-- Example:
324+--
325+-- <pre>
326+-- type MyApi = "books" :> Get [Book]
327+-- </pre>
328+data Get a
329+
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.
336+--
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)
342+
343+module Servant.API.Post
344+
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).
347+--
348+-- Example:
349+--
350+-- <pre>
351+-- -- POST /books
352+-- -- with a JSON encoded Book as the request body
353+-- -- returning the just-created Book
354+-- type MyApi = "books" :> ReqBody Book :> Post Book
355+-- </pre>
356+data Post a
357+
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.
364+--
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)
370+
371+module Servant.API.Delete
372+
373+-- | Combinator for DELETE requests.
374+--
375+-- Example:
376+--
377+-- <pre>
378+-- -- DELETE /books/:isbn
379+-- type MyApi = "books" :> Capture "isbn" Text :> Delete
380+-- </pre>
381+data Delete
382+
383+-- | If you have a <a>Delete</a> endpoint in your API, the handler for this
384+-- endpoint is meant to delete a resource.
385+--
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
393+
394+module Servant.API.Put
395+
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.
398+--
399+-- Example:
400+--
401+-- <pre>
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
405+-- </pre>
406+data Put a
407+
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.
414+--
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)
420+
421+
422+-- | QuasiQuoting utilities for API types.
423+--
424+-- <a>sitemap</a> allows you to write your type in a very natural way:
425+--
426+-- <pre>
427+-- [sitemap|
428+-- PUT hello String -> ()
429+-- POST hello/p:Int String -> ()
430+-- GET hello/?name:String Int
431+-- |]
432+-- </pre>
433+--
434+-- Will generate:
435+--
436+-- <pre>
437+-- "hello" :> ReqBody String :> Put ()
438+-- :<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()
439+-- :<|> "hello" :> QueryParam "name" String :> Get Int
440+-- </pre>
441+--
442+-- Note the <tt>/</tt> before a <tt>QueryParam</tt>!
443+module Servant.QQ
444+
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)
464+data Typ
465+Val :: String -> Typ
466+ReqArgVal :: String -> String -> Typ
467+parseTyp :: Parser Typ
468+parseEntry :: ExpSYM repr repr => Parser repr
469+blockComment :: Parser ()
470+inlineComment :: Parser ()
471+eol :: Parser String
472+eols :: Parser ()
473+parseAll :: Parser Type
474+
475+-- | The sitemap QuasiQuoter.
476+--
477+-- <ul>
478+-- <li><tt>...<i><a>var</a>:<a>type</a></i>...</tt> becomes a
479+-- capture</li>
480+-- <li><tt>.../?<a>var</a>:<a>type</a></tt> becomes a query
481+-- parameter</li>
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>
487+-- </ul>
488+--
489+-- Comments are allowed, and have the standard Haskell format
490+--
491+-- <ul>
492+-- <li><tt>--</tt> for inline</li>
493+-- <li><tt>{- ... -}</tt> for block</li>
494+-- </ul>
495+sitemap :: QuasiQuoter
496+instance ExpSYM Type Type
497+
498+
499+-- | Type safe internal links.
500+--
501+-- Provides the function <a>mkLink</a>:
502+--
503+-- <pre>
504+-- type API = Proxy ("hello" :> Get Int
505+-- :<a>|</a> "bye" :> QueryParam "name" String :> Post Bool)
506+--
507+-- api :: API
508+-- api = proxy
509+--
510+-- link1 :: Proxy ("hello" :> Get Int)
511+-- link1 = proxy
512+--
513+-- link2 :: Proxy ("hello" :> Delete)
514+-- link2 = proxy
515+--
516+-- mkLink link1 API -- typechecks, returns 'Link "/hello"'
517+--
518+-- mkLink link2 API -- doesn't typecheck
519+-- </pre>
520+--
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.
524+--
525+-- <b>N.B.:</b> <a>mkLink</a> assumes a capture matches any string
526+-- (without slashes).
527+module Servant.Utils.Links
528+
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
533+data Link
534+Link :: String -> Link
535+class VLinkHelper f
536+vlh :: VLinkHelper f => proxy f -> String
537+instance Show Link
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
542+
543+module Servant.API.Raw
544+
545+-- | Endpoint for plugging in your own Wai <a>Application</a>s.
546+--
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>.
550+--
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>.
556+data Raw
557+
558+-- | Just pass the request to the underlying application and serve its
559+-- response.
560+--
561+-- Example:
562+--
563+-- <pre>
564+-- type MyApi = "images" :> Raw
565+--
566+-- server :: Server MyApi
567+-- server = serveDirectory "/var/www/images"
568+-- </pre>
569+instance HasServer Raw
570+
571+
572+-- | This module defines a sever-side handler that lets you serve static
573+-- files.
574+--
575+-- <ul>
576+-- <li><a>serveDirectory</a> lets you serve anything that lives under a
577+-- particular directory on your filesystem.</li>
578+-- </ul>
579+module Servant.Utils.StaticFiles
580+
581+-- | Serve anything under the specified directory as a <a>Raw</a> endpoint.
582+--
583+-- <pre>
584+-- type MyApi = "static" :> Raw
585+--
586+-- server :: Server MyApi
587+-- server = serveDirectory "/var/www"
588+-- </pre>
589+--
590+-- would capture any request to <tt>/static/<something></tt> and
591+-- look for <tt><something></tt> under <tt>/var/www</tt>.
592+--
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
595+-- possible.
596+--
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
602+-- order.
603+serveDirectory :: FilePath -> Server Raw
604+
605+module Servant.API
606+
607+module Servant
608+
609+-- | A concrete, poly-kinded proxy type
610+data Proxy (t :: k) :: k -> *
611+Proxy :: Proxy