git.iko.soy/typeable/servant
on master help sign in
Built from 1defab0d2fb4457fafda0f645de24e5e7c28a95f
commit84b9ea271ec7c0fbff6e99ce23a65358ed6a948e authorAlp Mestanogullari <alpmestan@gmail.com> dateTue 2 Dec 2014, 18:34 (12 years ago) parentcec89c1
66 files changed+3465−13
.ghci−1 .travis.yml−12 Servant-API-Alternative.html+13 Servant-API-Capture.html+15 Servant-API-Delete.html+13 Servant-API-Get.html+12 Servant-API-Post.html+17 Servant-API-Put.html+15 Servant-API-QueryParam.html+45 Servant-API-Raw.html+11 Servant-API-ReqBody.html+14 Servant-API-Sub.html+56 Servant-API.html+4 Servant-Common-Text.html+7 Servant-QQ.html+17 Servant-Server.html+116 Servant-Utils-Links.html+23 Servant-Utils-StaticFiles.html+15 Servant.html+6 doc-index.html+4 frames.html+30 haddock-util.js+344 hslogo-16.png index-frames.html+4 index.html+4 mini_Servant-API-Alternative.html+4 mini_Servant-API-Capture.html+4 mini_Servant-API-Delete.html+4 mini_Servant-API-Get.html+4 mini_Servant-API-Post.html+4 mini_Servant-API-Put.html+4 mini_Servant-API-QueryParam.html+4 mini_Servant-API-Raw.html+4 mini_Servant-API-ReqBody.html+4 mini_Servant-API-Sub.html+4 mini_Servant-API.html+4 mini_Servant-Common-Text.html+4 mini_Servant-QQ.html+4 mini_Servant-Server.html+4 mini_Servant-Utils-Links.html+4 mini_Servant-Utils-StaticFiles.html+4 mini_Servant.html+4 minus.gif ocean.css+577 plus.gif servant.haddock servant.txt+611 src/Servant-API-Alternative.html+50 src/Servant-API-Capture.html+71 src/Servant-API-Delete.html+59 src/Servant-API-Get.html+58 src/Servant-API-Post.html+64 src/Servant-API-Put.html+63 src/Servant-API-QueryParam.html+173 src/Servant-API-Raw.html+43 src/Servant-API-ReqBody.html+60 src/Servant-API-Sub.html+47 src/Servant-API.html+62 src/Servant-Common-Text.html+141 src/Servant-QQ.html+209 src/Servant-Server.html+116 src/Servant-Utils-Links.html+121 src/Servant-Utils-StaticFiles.html+47 src/Servant.html+35 src/hscolour.css+5 synopsis.png
.ghcideleted−1
@@ -1 +0,0 @@
1−:set -itest -isrc -packagehspec2
.travis.ymldeleted−12
@@ -1,12 +0,0 @@
1−language: haskell
2−
3−notifications:
4− irc:
5− channels:
6− - "irc.freenode.org#servant"
7− template:
8− - "%{repository}#%{build_number} - %{commit} on %{branch} by %{author}: %{message}"
9− - "Build details: %{build_url} - Change view: %{compare_url}"
10− skip_join: true
11− on_success: change
12− on_failure: always
Servant-API-Alternative.htmlnew file+13
@@ -0,0 +1,13 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Alternative</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Alternative.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Alternative.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Alternative</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> a <a href="#t::-60--124--62-">:&lt;|&gt;</a> b = a <a href="#v::-60--124--62-">:&lt;|&gt;</a> b</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> a <a name="t::-60--124--62-" class="def">:&lt;|&gt;</a> b <span class="fixity">infixr 8</span><span class="rightedge"></span> <a href="src/Servant-API-Alternative.html#%3A%3C%7C%3E" class="link">Source</a></p><div class="doc"><p>Union of two APIs, first takes precedence in case of overlap.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Get [Book] -- GET /books
5+ :&lt;|&gt; &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book -- POST /books</pre></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src">a <a name="v::-60--124--62-" class="def">:&lt;|&gt;</a> b <span class="fixity">infixr 8</span><span class="rightedge"></span></td><td class="doc empty">&nbsp;</td></tr></table></div><div class="subs instances"><p id="control.i::-60--124--62-" class="caption collapser" onclick="toggleSection('i::-60--124--62-')">Instances</p><div id="section.i::-60--124--62-" class="show"><table><tr><td class="src">(<a href="Servant-Server.html#t:HasServer">HasServer</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> b) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:&lt;|&gt;)</a> a b)</td><td class="doc"><p>A server for <code>a <code><a href="Servant-API-Alternative.html#t::-60--124--62-">:&lt;|&gt;</a></code> b</code> first tries to match the request again the route
6+ represented by <code>a</code> and if it fails tries <code>b</code>. You must provide a request
7+ handler for each route.</p><pre>type MyApi = &quot;books&quot; :&gt; Get [Book] -- GET /books
8+ :&lt;|&gt; &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book -- POST /books
9+
10+server :: Server MyApi
11+server = listAllBooks :&lt;|&gt; postBook
12+ where listAllBooks = ...
13+ postBook book = ...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:&lt;|&gt;)</a> a b) = <a href="Servant-API-Alternative.html#t::-60--124--62-">(:&lt;|&gt;)</a> (<a href="Servant-Server.html#t:Server">Server</a> a) (<a href="Servant-Server.html#t:Server">Server</a> b)</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Capture.htmlnew file+15
@@ -0,0 +1,15 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Capture</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Capture.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Capture.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Capture</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Capture">Capture</a> sym a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Capture" class="def">Capture</a> sym a <a href="src/Servant-API-Capture.html#Capture" class="link">Source</a></p><div class="doc"><p>Capture a value from the request path under a certain type <code>a</code>.</p><p>Example:</p><pre> -- GET /books/:isbn
5+type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; Get Book</pre></div><div class="subs instances"><p id="control.i:Capture" class="caption collapser" onclick="toggleSection('i:Capture')">Instances</p><div id="section.i:Capture" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> in one of the endpoints for your API,
6+ this automatically requires your server-side handler to be a function
7+ that takes an argument of the type specified by the <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
8+ This lets servant worry about getting it from the URL and turning
9+ it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
10+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; Get Book
11+
12+server :: Server MyApi
13+server = getBook
14+ where getBook :: Text -&gt; EitherT (Int, String) IO Book
15+ getBook isbn = ...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout) = a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Delete.htmlnew file+13
@@ -0,0 +1,13 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Delete</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Delete.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Delete.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Delete</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Delete">Delete</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Delete" class="def">Delete</a> <a href="src/Servant-API-Delete.html#Delete" class="link">Source</a></p><div class="doc"><p>Combinator for DELETE requests.</p><p>Example:</p><pre> -- DELETE /books/:isbn
5+type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; Delete</pre></div><div class="subs instances"><p id="control.i:Delete" class="caption collapser" onclick="toggleSection('i:Delete')">Instances</p><div id="section.i:Delete" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc"><p>If you have a <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code> endpoint in your API,
6+ the handler for this endpoint is meant to delete
7+ a resource.</p><p>The code of the handler will, just like
8+ for <code><a href="Servant-API-Get.html#t:Get">Get</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code> and
9+ <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, run in <code>EitherT (Int, String) IO ()</code>.
10+ The <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message
11+ to be returned. You can use <code><a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#v:left">left</a></code> to
12+ painlessly error out if the conditions for a successful deletion
13+ are not met.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> * <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a> = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> ()</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Get.htmlnew file+12
@@ -0,0 +1,12 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Get</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Get.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Get.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Get</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Get">Get</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Get" class="def">Get</a> a <a href="src/Servant-API-Get.html#Get" class="link">Source</a></p><div class="doc"><p>Endpoint for simple GET requests. Serves the result as JSON.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Get [Book]</pre></div><div class="subs instances"><p id="control.i:Get" class="caption collapser" onclick="toggleSection('i:Get')">Instances</p><div id="section.i:Get" class="show"><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Get.html#t:Get">Get</a> x)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> result =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Get.html#t:Get">Get</a></code> endpoint,
5+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code>
6+ and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
7+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
8+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
9+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
10+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
11+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
12+ yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -&gt; *) <a href="Servant-API-Get.html#t:Get">Get</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> result</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Post.htmlnew file+17
@@ -0,0 +1,17 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Post</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Post.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Post.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Post</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Post">Post</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Post" class="def">Post</a> a <a href="src/Servant-API-Post.html#Post" class="link">Source</a></p><div class="doc"><p>Endpoint for POST requests. The type variable represents the type of the
5+ response body (not the request body, use <code><a href="Servant-API-RQBody.html#t:RQBody">RQBody</a></code> for
6+ that).</p><p>Example:</p><pre> -- POST /books
7+ -- with a JSON encoded Book as the request body
8+ -- returning the just-created Book
9+type MyApi = &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book</pre></div><div class="subs instances"><p id="control.i:Post" class="caption collapser" onclick="toggleSection('i:Post')">Instances</p><div id="section.i:Post" class="show"><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Post.html#t:Post">Post</a> x)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Post.html#t:Post">Post</a></code> endpoint,
10+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
11+ and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
12+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
13+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
14+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
15+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
16+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
17+ yielding status code 201 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -&gt; *) <a href="Servant-API-Post.html#t:Post">Post</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> a</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Put.htmlnew file+15
@@ -0,0 +1,15 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Put</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Put.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Put.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Put</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Put">Put</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Put" class="def">Put</a> a <a href="src/Servant-API-Put.html#Put" class="link">Source</a></p><div class="doc"><p>Endpoint for PUT requests, usually used to update a ressource.
5+ The type <code>a</code> is the type of the response body that's returned.</p><p>Example:</p><pre>-- PUT /books/:isbn
6+-- with a Book as request body, returning the updated Book
7+type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; ReqBody Book :&gt; Put Book</pre></div><div class="subs instances"><p id="control.i:Put" class="caption collapser" onclick="toggleSection('i:Put')">Instances</p><div id="section.i:Put" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Put.html#t:Put">Put</a></code> endpoint,
8+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
9+ and <code><a href="Servant-API-Post.html#t:Post">Post</a></code>, the handler code runs in the
10+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
11+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
12+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
13+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
14+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
15+ yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (* -&gt; *) <a href="Servant-API-Put.html#t:Put">Put</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a) = <a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#t:EitherT">EitherT</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a>, <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a>) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> a</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-QueryParam.htmlnew file+45
@@ -0,0 +1,45 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.QueryParam</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-QueryParam.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-QueryParam.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.QueryParam</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:QueryParam">QueryParam</a> sym a</li><li class="src short"><span class="keyword">data</span> <a href="#t:QueryParams">QueryParams</a> sym a</li><li class="src short"><span class="keyword">data</span> <a href="#t:QueryFlag">QueryFlag</a> sym</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryParam" class="def">QueryParam</a> sym a <a href="src/Servant-API-QueryParam.html#QueryParam" class="link">Source</a></p><div class="doc"><p>Lookup the value associated to the <code>sym</code> query string parameter
5+ and try to extract it as a value of type <code>a</code>.</p><p>Example:</p><pre>-- /books?author=&lt;author name&gt;
6+type MyApi = &quot;books&quot; :&gt; QueryParam &quot;author&quot; Text :&gt; Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryParam" class="caption collapser" onclick="toggleSection('i:QueryParam')">Instances</p><div id="section.i:QueryParam" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> &quot;author&quot; Text</code> in one of the endpoints for your API,
7+ this automatically requires your server-side handler to be a function
8+ that takes an argument of type <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>This lets servant worry about looking it up in the query string
9+ and turning it into a value of the type you specify, enclosed
10+ in <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
11+ hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
12+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParam &quot;author&quot; Text :&gt; Get [Book]
13+
14+server :: Server MyApi
15+server = getBooksBy
16+ where getBooksBy :: Maybe Text -&gt; EitherT (Int, String) IO [Book]
17+ getBooksBy Nothing = ...return all books...
18+ getBooksBy (Just author) = ...return books by the given author...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryParams" class="def">QueryParams</a> sym a <a href="src/Servant-API-QueryParam.html#QueryParams" class="link">Source</a></p><div class="doc"><p>Lookup the values associated to the <code>sym</code> query string parameter
19+ and try to extract it as a value of type <code>[a]</code>. This is typically
20+ meant to support query string parameters of the form
21+ <code>param[]=val1&amp;param[]=val2</code> and so on. Note that servant doesn't actually
22+ require the <code>[]</code>s and will fetch the values just fine with
23+ <code>param=val1&amp;param=val2</code>, too.</p><p>Example:</p><pre>-- /books?authors[]=&lt;author1&gt;&amp;authors[]=&lt;author2&gt;&amp;...
24+type MyApi = &quot;books&quot; :&gt; QueryParams &quot;authors&quot; Text :&gt; Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryParams" class="caption collapser" onclick="toggleSection('i:QueryParams')">Instances</p><div id="section.i:QueryParams" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> &quot;authors&quot; Text</code> in one of the endpoints for your API,
25+ this automatically requires your server-side handler to be a function
26+ that takes an argument of type <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
27+ associated to <code>authors</code> and turning each of them into a value of
28+ the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
29+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParams &quot;authors&quot; Text :&gt; Get [Book]
30+
31+server :: Server MyApi
32+server = getBooksBy
33+ where getBooksBy :: [Text] -&gt; EitherT (Int, String) IO [Book]
34+ getBooksBy authors = ...return all books by these authors...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = [a] -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:QueryFlag" class="def">QueryFlag</a> sym <a href="src/Servant-API-QueryParam.html#QueryFlag" class="link">Source</a></p><div class="doc"><p>Lookup a potentially value-less query string parameter
35+ with boolean semantics. If the param <code>sym</code> is there without any value,
36+ or if it's there with value &quot;true&quot; or &quot;1&quot;, it's interpreted as <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></code>.
37+ Otherwise, it's interpreted as <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></code>.</p><p>Example:</p><pre>-- /books?published
38+type MyApi = &quot;books&quot; :&gt; QueryFlag &quot;published&quot; :&gt; Get [Book]</pre></div><div class="subs instances"><p id="control.i:QueryFlag" class="caption collapser" onclick="toggleSection('i:QueryFlag')">Instances</p><div id="section.i:QueryFlag" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> &quot;published&quot;</code> in one of the endpoints for your API,
39+ this automatically requires your server-side handler to be a function
40+ that takes an argument of type <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryFlag &quot;published&quot; :&gt; Get [Book]
41+
42+server :: Server MyApi
43+server = getBooks
44+ where getBooks :: Bool -&gt; EitherT (Int, String) IO [Book]
45+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Raw.htmlnew file+11
@@ -0,0 +1,11 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Raw</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Raw.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Raw.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Raw</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:Raw">Raw</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Raw" class="def">Raw</a> <a href="src/Servant-API-Raw.html#Raw" class="link">Source</a></p><div class="doc"><p>Endpoint for plugging in your own Wai <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>s.</p><p>The given <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code> will get the request as received by the server, potentially with
5+ a modified (stripped) <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#v:pathInfo">pathInfo</a></code> if the <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code> is being routed with <code><a href="Servant-API-Sub.html#t::-62-">:&gt;</a></code>.</p><p>In addition to just letting you plug in your existing WAI <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>s,
6+ this can also be used with <code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code> to serve
7+ static files stored in a particular directory on your filesystem, or to serve
8+ your API's documentation with <code><a href="Servant-Utils-StaticFiles.html#v:serveDocumentation">serveDocumentation</a></code>.</p></div><div class="subs instances"><p id="control.i:Raw" class="caption collapser" onclick="toggleSection('i:Raw')">Instances</p><div id="section.i:Raw" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></td><td class="doc"><p>Just pass the request to the underlying application and serve its response.</p><p>Example:</p><pre>type MyApi = &quot;images&quot; :&gt; Raw
9+
10+server :: Server MyApi
11+server = serveDirectory &quot;/var/www/images&quot;</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a> = <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-ReqBody.htmlnew file+14
@@ -0,0 +1,14 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.ReqBody</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-ReqBody.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-ReqBody.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.ReqBody</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> <a href="#t:ReqBody">ReqBody</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:ReqBody" class="def">ReqBody</a> a <a href="src/Servant-API-ReqBody.html#ReqBody" class="link">Source</a></p><div class="doc"><p>Extract the request body as a value of type <code>a</code>.</p><p>Example:</p><pre> -- POST /books
5+type MyApi = &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book</pre></div><div class="subs instances"><p id="control.i:ReqBody" class="caption collapser" onclick="toggleSection('i:ReqBody')">Instances</p><div id="section.i:ReqBody" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> in one of the endpoints for your API,
6+ this automatically requires your server-side handler to be a function
7+ that takes an argument of the type specified by <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
8+ This lets servant worry about extracting it from the request and turning
9+ it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book
10+
11+server :: Server MyApi
12+server = postBook
13+ where postBook :: Book -&gt; EitherT (Int, String) IO Book
14+ postBook book = ...insert into your db...</pre></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout) = a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API-Sub.htmlnew file+56
@@ -0,0 +1,56 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Sub</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API-Sub.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API-Sub.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API.Sub</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">data</span> path <a href="#t::-62-">:&gt;</a> a = (<a href="Servant.html#t:Proxy">Proxy</a> path) <a href="#v::-62-">:&gt;</a> a</li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">data</span> path <a name="t::-62-" class="def">:&gt;</a> a <span class="fixity">infixr 9</span><span class="rightedge"></span> <a href="src/Servant-API-Sub.html#%3A%3E" class="link">Source</a></p><div class="doc"><p>The contained API (second argument) can be found under <code>(&quot;/&quot; ++ path)</code>
5+ (path being the first argument).</p><p>Example:</p><pre>-- GET /hello/world
6+-- returning a JSON encoded World value
7+type MyApi = &quot;hello&quot; :&gt; &quot;world&quot; :&gt; Get World</pre></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src">(<a href="Servant.html#t:Proxy">Proxy</a> path) <a name="v::-62-" class="def">:&gt;</a> a <span class="fixity">infixr 9</span><span class="rightedge"></span></td><td class="doc empty">&nbsp;</td></tr></table></div><div class="subs instances"><p id="control.i::-62-" class="caption collapser" onclick="toggleSection('i::-62-')">Instances</p><div id="section.i::-62-" class="show"><table><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> s, <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * e) =&gt; <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> s e)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> in one of the endpoints for your API,
8+ this automatically requires your server-side handler to be a function
9+ that takes an argument of the type specified by the <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
10+ This lets servant worry about getting it from the URL and turning
11+ it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
12+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; Get Book
13+
14+server :: Server MyApi
15+server = getBook
16+ where getBook :: Text -&gt; EitherT (Int, String) IO Book
17+ getBook isbn = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> &quot;published&quot;</code> in one of the endpoints for your API,
18+ this automatically requires your server-side handler to be a function
19+ that takes an argument of type <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryFlag &quot;published&quot; :&gt; Get [Book]
20+
21+server :: Server MyApi
22+server = getBooks
23+ where getBooks :: Bool -&gt; EitherT (Int, String) IO [Book]
24+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> &quot;authors&quot; Text</code> in one of the endpoints for your API,
25+ this automatically requires your server-side handler to be a function
26+ that takes an argument of type <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
27+ associated to <code>authors</code> and turning each of them into a value of
28+ the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
29+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParams &quot;authors&quot; Text :&gt; Get [Book]
30+
31+server :: Server MyApi
32+server = getBooksBy
33+ where getBooksBy :: [Text] -&gt; EitherT (Int, String) IO [Book]
34+ getBooksBy authors = ...return all books by these authors...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> &quot;author&quot; Text</code> in one of the endpoints for your API,
35+ this automatically requires your server-side handler to be a function
36+ that takes an argument of type <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>This lets servant worry about looking it up in the query string
37+ and turning it into a value of the type you specify, enclosed
38+ in <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
39+ hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
40+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParam &quot;author&quot; Text :&gt; Get [Book]
41+
42+server :: Server MyApi
43+server = getBooksBy
44+ where getBooksBy :: Maybe Text -&gt; EitherT (Int, String) IO [Book]
45+ getBooksBy Nothing = ...return all books...
46+ getBooksBy (Just author) = ...return books by the given author...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> in one of the endpoints for your API,
47+ this automatically requires your server-side handler to be a function
48+ that takes an argument of the type specified by <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
49+ This lets servant worry about extracting it from the request and turning
50+ it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book
51+
52+server :: Server MyApi
53+server = postBook
54+ where postBook :: Book -&gt; EitherT (Int, String) IO Book
55+ postBook book = ...insert into your db...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> path, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout)</td><td class="doc"><p>Make sure the incoming request starts with <code>&quot;/path&quot;</code>, strip it and
56+ pass the rest of the request path to <code>sublayout</code>.</p></td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout) = a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = [a] -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout) = a -&gt; <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:Server">Server</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout) = <a href="Servant-Server.html#t:Server">Server</a> sublayout</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-API.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-API.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-API.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.API</p></div><div id="table-of-contents"><p class="caption">Contents</p><ul><li><a href="#g:1">Combinators</a></li><li><a href="#g:2">Accessing information from the request</a></li><li><a href="#g:3">Actual endpoints, distinguished by HTTP method</a></li><li><a href="#g:4">Untyped endpoints</a></li><li><a href="#g:5">Utilities</a></li></ul></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short">module <a href="Servant-API-Sub.html">Servant.API.Sub</a></li><li class="src short">module <a href="Servant-API-Alternative.html">Servant.API.Alternative</a></li><li class="src short">module <a href="Servant-API-Capture.html">Servant.API.Capture</a></li><li class="src short">module <a href="Servant-API-QueryParam.html">Servant.API.QueryParam</a></li><li class="src short">module <a href="Servant-API-ReqBody.html">Servant.API.ReqBody</a></li><li class="src short">module <a href="Servant-API-Get.html">Servant.API.Get</a></li><li class="src short">module <a href="Servant-API-Post.html">Servant.API.Post</a></li><li class="src short">module <a href="Servant-API-Delete.html">Servant.API.Delete</a></li><li class="src short">module <a href="Servant-API-Put.html">Servant.API.Put</a></li><li class="src short">module <a href="Servant-API-Raw.html">Servant.API.Raw</a></li><li class="src short">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></li><li class="src short">module <a href="Servant-QQ.html">Servant.QQ</a></li><li class="src short">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></li></ul></div><div id="interface"><h1 id="g:1">Combinators</h1><div class="doc"><p>Type-level combinator for expressing subrouting: <code><code><a href="Servant-API-Sub.html#t::-62-">:&gt;</a></code></code></p></div><div class="top"><p class="src">module <a href="Servant-API-Sub.html">Servant.API.Sub</a></p></div><div class="doc"><p>Type-level combinator for alternative endpoints: <code><code><a href="Servant-API-Alternative.html#t::-60--124--62-">:&lt;|&gt;</a></code></code></p></div><div class="top"><p class="src">module <a href="Servant-API-Alternative.html">Servant.API.Alternative</a></p></div><h1 id="g:2">Accessing information from the request</h1><div class="doc"><p>Capturing parts of the url path as parsed values: <code><code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code></code></p></div><div class="top"><p class="src">module <a href="Servant-API-Capture.html">Servant.API.Capture</a></p></div><div class="doc"><p>Retrieving parameters from the query string of the <code>URI</code>: <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code></code></p></div><div class="top"><p class="src">module <a href="Servant-API-QueryParam.html">Servant.API.QueryParam</a></p></div><div class="doc"><p>Accessing the request body as a JSON-encoded type: <code><code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code></code></p></div><div class="top"><p class="src">module <a href="Servant-API-ReqBody.html">Servant.API.ReqBody</a></p></div><h1 id="g:3">Actual endpoints, distinguished by HTTP method</h1><div class="doc"><p>GET requests</p></div><div class="top"><p class="src">module <a href="Servant-API-Get.html">Servant.API.Get</a></p></div><div class="doc"><p>POST requests</p></div><div class="top"><p class="src">module <a href="Servant-API-Post.html">Servant.API.Post</a></p></div><div class="doc"><p>DELETE requests</p></div><div class="top"><p class="src">module <a href="Servant-API-Delete.html">Servant.API.Delete</a></p></div><div class="doc"><p>PUT requests</p></div><div class="top"><p class="src">module <a href="Servant-API-Put.html">Servant.API.Put</a></p></div><h1 id="g:4">Untyped endpoints</h1><div class="doc"><p>Plugging in a wai <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>, serving directories</p></div><div class="top"><p class="src">module <a href="Servant-API-Raw.html">Servant.API.Raw</a></p></div><div class="top"><p class="src">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></p></div><h1 id="g:5">Utilities</h1><div class="doc"><p>QuasiQuotes for endpoints</p></div><div class="top"><p class="src">module <a href="Servant-QQ.html">Servant.QQ</a></p></div><div class="doc"><p>Type-safe internal URLs</p></div><div class="top"><p class="src">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></p></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-Common-Text.htmlnew file+7
@@ -0,0 +1,7 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Common.Text</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-Common-Text.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Common-Text.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>Safe-Inferred</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Common.Text</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">class</span> <a href="#t:FromText">FromText</a> a <span class="keyword">where</span><ul class="subs"><li><a href="#v:fromText">fromText</a> :: <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a</li></ul></li><li class="src short"><span class="keyword">class</span> <a href="#t:ToText">ToText</a> a <span class="keyword">where</span><ul class="subs"><li><a href="#v:toText">toText</a> :: a -&gt; <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></li></ul></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:FromText" class="def">FromText</a> a <span class="keyword">where</span> <a href="src/Servant-Common-Text.html#FromText" class="link">Source</a></p><div class="doc"><p>For getting values from url captures and query string parameters</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:fromText" class="def">fromText</a> :: <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a> a <a href="src/Servant-Common-Text.html#fromText" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:FromText" class="caption collapser" onclick="toggleSection('i:FromText')">Instances</p><div id="section.i:FromText" class="show"><table><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></td><td class="doc"><pre>fromText &quot;true&quot; = Just True
5+fromText &quot;false&quot; = Just False
6+fromText _ = Nothing</pre></td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Double">Double</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Float">Float</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int8">Int8</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int16">Int16</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int32">Int32</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int64">Int64</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Integer">Integer</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word">Word</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word8">Word8</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word16">Word16</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word32">Word32</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word64">Word64</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:FromText">FromText</a> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:ToText" class="def">ToText</a> a <span class="keyword">where</span> <a href="src/Servant-Common-Text.html#ToText" class="link">Source</a></p><div class="doc"><p>For putting values in paths and query string parameters</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:toText" class="def">toText</a> :: a -&gt; <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a> <a href="src/Servant-Common-Text.html#toText" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:ToText" class="caption collapser" onclick="toggleSection('i:ToText')">Instances</p><div id="section.i:ToText" class="show"><table><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></td><td class="doc"><pre>toText True = &quot;true&quot;
7+toText False = &quot;false&quot;</pre></td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Double">Double</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Float">Float</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int8">Int8</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int16">Int16</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int32">Int32</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int64">Int64</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Integer">Integer</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word">Word</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word8">Word8</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word16">Word16</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word32">Word32</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Word.html#t:Word64">Word64</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Common-Text.html#t:ToText">ToText</a> <a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-QQ.htmlnew file+17
@@ -0,0 +1,17 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.QQ</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-QQ.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-QQ.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.QQ</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>QuasiQuoting utilities for API types.</p><p><code><a href="Servant-QQ.html#v:sitemap">sitemap</a></code> allows you to write your type in a very natural way:</p><pre>[sitemap|
5+PUT hello String -&gt; ()
6+POST hello/p:Int String -&gt; ()
7+GET hello/?name:String Int
8+|]
9+</pre><p>Will generate:</p><pre> &quot;hello&quot; :&gt; ReqBody String :&gt; Put ()
10+ :&lt;|&gt; &quot;hello&quot; :&gt; Capture &quot;p&quot; Int :&gt; ReqBody String :&gt; Post ()
11+ :&lt;|&gt; &quot;hello&quot; :&gt; QueryParam &quot;name&quot; String :&gt; Get Int
12+</pre><p>Note the <code>/</code> before a <code>QueryParam</code>!</p></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">class</span> <a href="#t:ExpSYM">ExpSYM</a> repr' repr | repr -&gt; repr', repr' -&gt; repr <span class="keyword">where</span><ul class="subs"><li><a href="#v:lit">lit</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr' -&gt; repr</li><li><a href="#v:capture">capture</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr</li><li><a href="#v:reqBody">reqBody</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr</li><li><a href="#v:queryParam">queryParam</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr</li><li><a href="#v:conj">conj</a> :: repr' -&gt; repr -&gt; repr</li><li><a href="#v:get">get</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr</li><li><a href="#v:post">post</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr</li><li><a href="#v:put">put</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr</li><li><a href="#v:delete">delete</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr</li></ul></li><li class="src short"><a href="#v:-62-:">(&gt;:)</a> :: <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> -&gt; <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> -&gt; <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a></li><li class="src short"><a href="#v:parseMethod">parseMethod</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr' repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr)</li><li class="src short"><a href="#v:parseUrlSegment">parseUrlSegment</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (repr -&gt; repr)</li><li class="src short"><a href="#v:parseUrl">parseUrl</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (repr -&gt; repr)</li><li class="src short"><span class="keyword">data</span> <a href="#t:Typ">Typ</a><ul class="subs"><li>= <a href="#v:Val">Val</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></li><li>| <a href="#v:ReqArgVal">ReqArgVal</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></li></ul></li><li class="src short"><a href="#v:parseTyp">parseTyp</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="Servant-QQ.html#t:Typ">Typ</a></li><li class="src short"><a href="#v:parseEntry">parseEntry</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> repr</li><li class="src short"><a href="#v:blockComment">blockComment</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> ()</li><li class="src short"><a href="#v:inlineComment">inlineComment</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> ()</li><li class="src short"><a href="#v:eol">eol</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></li><li class="src short"><a href="#v:eols">eols</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> ()</li><li class="src short"><a href="#v:parseAll">parseAll</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a></li><li class="src short"><a href="#v:sitemap">sitemap</a> :: <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Quote.html#t:QuasiQuoter">QuasiQuoter</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:ExpSYM" class="def">ExpSYM</a> repr' repr | repr -&gt; repr', repr' -&gt; repr <span class="keyword">where</span> <a href="src/Servant-QQ.html#ExpSYM" class="link">Source</a></p><div class="doc"><p>Finally-tagless encoding for our DSL.
13+ Keeping <code>repr'</code> and <code>repr</code> distinct when writing functions with an
14+ <code>ExpSYM</code> context ensures certain invariants (for instance, that there is
15+ only one of <code><a href="Servant-QQ.html#v:get">get</a></code>, <code><a href="Servant-QQ.html#v:post">post</a></code>, <code><a href="Servant-QQ.html#v:put">put</a></code>, and <code><a href="Servant-QQ.html#v:delete">delete</a></code> in a value), but
16+ sometimes requires a little more work.</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:lit" class="def">lit</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr' -&gt; repr <a href="src/Servant-QQ.html#lit" class="link">Source</a></p><p class="src"><a name="v:capture" class="def">capture</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr <a href="src/Servant-QQ.html#capture" class="link">Source</a></p><p class="src"><a name="v:reqBody" class="def">reqBody</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr <a href="src/Servant-QQ.html#reqBody" class="link">Source</a></p><p class="src"><a name="v:queryParam" class="def">queryParam</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr -&gt; repr <a href="src/Servant-QQ.html#queryParam" class="link">Source</a></p><p class="src"><a name="v:conj" class="def">conj</a> :: repr' -&gt; repr -&gt; repr <a href="src/Servant-QQ.html#conj" class="link">Source</a></p><p class="src"><a name="v:get" class="def">get</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr <a href="src/Servant-QQ.html#get" class="link">Source</a></p><p class="src"><a name="v:post" class="def">post</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr <a href="src/Servant-QQ.html#post" class="link">Source</a></p><p class="src"><a name="v:put" class="def">put</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr <a href="src/Servant-QQ.html#put" class="link">Source</a></p><p class="src"><a name="v:delete" class="def">delete</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr <a href="src/Servant-QQ.html#delete" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:ExpSYM" class="caption collapser" onclick="toggleSection('i:ExpSYM')">Instances</p><div id="section.i:ExpSYM" class="show"><table><tr><td class="src"><a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><a name="v:-62-:" class="def">(&gt;:)</a> :: <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> -&gt; <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> -&gt; <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> <span class="fixity">infixr 6</span><span class="rightedge"></span> <a href="src/Servant-QQ.html#%3E%3A" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:parseMethod" class="def">parseMethod</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr' repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> -&gt; repr) <a href="src/Servant-QQ.html#parseMethod" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:parseUrlSegment" class="def">parseUrlSegment</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (repr -&gt; repr) <a href="src/Servant-QQ.html#parseUrlSegment" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:parseUrl" class="def">parseUrl</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> (repr -&gt; repr) <a href="src/Servant-QQ.html#parseUrl" class="link">Source</a></p></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Typ" class="def">Typ</a> <a href="src/Servant-QQ.html#Typ" class="link">Source</a></p><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:Val" class="def">Val</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a name="v:ReqArgVal" class="def">ReqArgVal</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><a name="v:parseTyp" class="def">parseTyp</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="Servant-QQ.html#t:Typ">Typ</a> <a href="src/Servant-QQ.html#parseTyp" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:parseEntry" class="def">parseEntry</a> :: <a href="Servant-QQ.html#t:ExpSYM">ExpSYM</a> repr repr =&gt; <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> repr <a href="src/Servant-QQ.html#parseEntry" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:blockComment" class="def">blockComment</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> () <a href="src/Servant-QQ.html#blockComment" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:inlineComment" class="def">inlineComment</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> () <a href="src/Servant-QQ.html#inlineComment" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:eol" class="def">eol</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> <a href="src/Servant-QQ.html#eol" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:eols" class="def">eols</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> () <a href="src/Servant-QQ.html#eols" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:parseAll" class="def">parseAll</a> :: <a href="https://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-String.html#t:Parser">Parser</a> <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Syntax.html#t:Type">Type</a> <a href="src/Servant-QQ.html#parseAll" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:sitemap" class="def">sitemap</a> :: <a href="https://hackage.haskell.org/package/template-haskell-2.9.0.0/docs/Language-Haskell-TH-Quote.html#t:QuasiQuoter">QuasiQuoter</a> <a href="src/Servant-QQ.html#sitemap" class="link">Source</a></p><div class="doc"><p>The sitemap QuasiQuoter.</p><ul><li><code>...<em><a href="var">var</a>:<a href="type">type</a></em>...</code> becomes a capture</li><li><code>.../?<a href="var">var</a>:<a href="type">type</a></code> becomes a query parameter</li><li><code><a href="method">method</a> ... <a href="typ">typ</a></code> becomes a method returning <code><a href="typ">typ</a></code></li><li><code><a href="method">method</a> ... <a href="typ1">typ1</a> -&gt; <a href="typ2">typ2</a></code> becomes a method with request
17+ body of <code><a href="typ1">typ1</a></code> and returning <code><a href="typ2">typ2</a></code></li></ul><p>Comments are allowed, and have the standard Haskell format</p><ul><li><code>--</code> for inline</li><li><code>{- ... -}</code> for block</li></ul></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-Server.htmlnew file+116
@@ -0,0 +1,116 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Server</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-Server.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Server.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Server</p></div><div id="table-of-contents"><p class="caption">Contents</p><ul><li><a href="#g:1">Implementing Servers</a></li><li><a href="#g:2">Route mismatch</a></li></ul></div><div id="description"><p class="caption">Description</p><div class="doc"><p>This module lets you implement <code><a href="Servant-Server.html#t:Server">Server</a></code>s for defined APIs. You'll
5+ most likely just need <code><a href="Servant-Server.html#v:serve">serve</a></code>.</p></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><a href="#v:serve">serve</a> :: <a href="Servant-Server.html#t:HasServer">HasServer</a> layout =&gt; <a href="Servant.html#t:Proxy">Proxy</a> layout -&gt; <a href="Servant-Server.html#t:Server">Server</a> layout -&gt; <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></li><li class="src short"><a href="#v:toApplication">toApplication</a> :: <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> -&gt; <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></li><li class="src short"><span class="keyword">data</span> <a href="#t:RouteMismatch">RouteMismatch</a><ul class="subs"><li>= <a href="#v:NotFound">NotFound</a></li><li>| <a href="#v:WrongMethod">WrongMethod</a></li><li>| <a href="#v:InvalidBody">InvalidBody</a></li></ul></li><li class="src short"><span class="keyword">newtype</span> <a href="#t:RouteResult">RouteResult</a> a = <a href="#v:RR">RR</a> {<ul class="subs"><li><a href="#v:routeResult">routeResult</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> a</li></ul>}</li><li class="src short"><a href="#v:failWith">failWith</a> :: <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> -&gt; <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a</li><li class="src short"><a href="#v:succeedWith">succeedWith</a> :: a -&gt; <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a</li><li class="src short"><a href="#v:isMismatch">isMismatch</a> :: <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></li><li class="src short"><span class="keyword">type</span> <a href="#t:RoutingApplication">RoutingApplication</a> = <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Request">Request</a> -&gt; (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Response">Response</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a>) -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a></li><li class="src short"><span class="keyword">class</span> <a href="#t:HasServer">HasServer</a> layout <span class="keyword">where</span><ul class="subs"><li><span class="keyword">type</span> <a href="#t:Server">Server</a> layout :: *</li><li><a href="#v:route">route</a> :: <a href="Servant.html#t:Proxy">Proxy</a> layout -&gt; <a href="Servant-Server.html#t:Server">Server</a> layout -&gt; <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a></li></ul></li></ul></div><div id="interface"><h1 id="g:1">Implementing Servers</h1><div class="top"><p class="src"><a name="v:serve" class="def">serve</a> :: <a href="Servant-Server.html#t:HasServer">HasServer</a> layout =&gt; <a href="Servant.html#t:Proxy">Proxy</a> layout -&gt; <a href="Servant-Server.html#t:Server">Server</a> layout -&gt; <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a> <a href="src/Servant-Server.html#serve" class="link">Source</a></p><div class="doc"><p><code><a href="Servant-Server.html#v:serve">serve</a></code> allows you to implement an API and produce a wai <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a></code>.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Get [Book] -- GET /books
6+ :&lt;|&gt; &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book -- POST /books
7+
8+server :: Server MyApi
9+server = listAllBooks :&lt;|&gt; postBook
10+ where listAllBooks = ...
11+ postBook book = ...
12+
13+app :: Application
14+app = serve myApi server
15+
16+main :: IO ()
17+main = Network.Wai.Handler.Warp.run 8080 app</pre></div></div><div class="top"><p class="src"><a name="v:toApplication" class="def">toApplication</a> :: <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> -&gt; <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Application">Application</a> <a href="src/Servant-Server.html#toApplication" class="link">Source</a></p></div><h1 id="g:2">Route mismatch</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:RouteMismatch" class="def">RouteMismatch</a> <a href="src/Servant-Server.html#RouteMismatch" class="link">Source</a></p><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:NotFound" class="def">NotFound</a></td><td class="doc"><p>the usual &quot;not found&quot; error</p></td></tr><tr><td class="src"><a name="v:WrongMethod" class="def">WrongMethod</a></td><td class="doc"><p>a more informative &quot;you just got the HTTP method wrong&quot; error</p></td></tr><tr><td class="src"><a name="v:InvalidBody" class="def">InvalidBody</a></td><td class="doc"><p>an even more informative &quot;your json request body wasn't valid&quot; error</p></td></tr></table></div><div class="subs instances"><p id="control.i:RouteMismatch" class="caption collapser" onclick="toggleSection('i:RouteMismatch')">Instances</p><div id="section.i:RouteMismatch" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></td><td class="doc"><pre>&gt; mempty = NotFound
18+&gt;
19+&gt; NotFound <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> x = x
20+&gt; WrongMethod <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> InvalidBody = InvalidBody
21+&gt; WrongMethod <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> _ = WrongMethod
22+&gt; InvalidBody <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#v:mappend">mappend</a></code> _ = InvalidBody
23+</pre></td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">newtype</span> <a name="t:RouteResult" class="def">RouteResult</a> a <a href="src/Servant-Server.html#RouteResult" class="link">Source</a></p><div class="doc"><p>A wrapper around <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a></code> <code><a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a></code> a</code>.</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:RR" class="def">RR</a></td><td class="doc empty">&nbsp;</td></tr><tr><td colspan="2"><div class="subs fields"><p class="caption">Fields</p><dl><dt class="src"><a name="v:routeResult" class="def">routeResult</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#t:Either">Either</a> <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> a</dt><dd class="doc empty">&nbsp;</dd></dl><div class="clear"></div></div></td></tr></table></div><div class="subs instances"><p id="control.i:RouteResult" class="caption collapser" onclick="toggleSection('i:RouteResult')">Instances</p><div id="section.i:RouteResult" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> a =&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> a =&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> a)</td><td class="doc"><p>If we get a <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#v:Right">Right</a></code>, it has precedence over everything else.</p><p>This in particular means that if we could get several <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Either.html#v:Right">Right</a></code>s,
24+ only the first we encounter would be taken into account.</p></td></tr></table></div></div></div><div class="top"><p class="src"><a name="v:failWith" class="def">failWith</a> :: <a href="Servant-Server.html#t:RouteMismatch">RouteMismatch</a> -&gt; <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a <a href="src/Servant-Server.html#failWith" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:succeedWith" class="def">succeedWith</a> :: a -&gt; <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a <a href="src/Servant-Server.html#succeedWith" class="link">Source</a></p></div><div class="top"><p class="src"><a name="v:isMismatch" class="def">isMismatch</a> :: <a href="Servant-Server.html#t:RouteResult">RouteResult</a> a -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> <a href="src/Servant-Server.html#isMismatch" class="link">Source</a></p></div><div class="top"><p class="src"><span class="keyword">type</span> <a name="t:RoutingApplication" class="def">RoutingApplication</a> <a href="src/Servant-Server.html#RoutingApplication" class="link">Source</a></p><div class="subs arguments"><p class="caption">Arguments</p><table><tr><td class="src">&nbsp;= <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Request">Request</a></td><td class="doc"><p>the request, the field <code><a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#v:pathInfo">pathInfo</a></code> may be modified by url routing</p></td></tr><tr><td class="src">-&gt; (<a href="Servant-Server.html#t:RouteResult">RouteResult</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:Response">Response</a> -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a>)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src">-&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:IO">IO</a> <a href="https://hackage.haskell.org/package/wai-3.0.2/docs/Network-Wai.html#t:ResponseReceived">ResponseReceived</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:HasServer" class="def">HasServer</a> layout <span class="keyword">where</span> <a href="src/Servant-Server.html#HasServer" class="link">Source</a></p><div class="subs associated-types"><p class="caption">Associated Types</p><p class="src"><span class="keyword">type</span> <a name="t:Server" class="def">Server</a> layout :: * <a href="src/Servant-Server.html#Server" class="link">Source</a></p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:route" class="def">route</a> :: <a href="Servant.html#t:Proxy">Proxy</a> layout -&gt; <a href="Servant-Server.html#t:Server">Server</a> layout -&gt; <a href="Servant-Server.html#t:RoutingApplication">RoutingApplication</a> <a href="src/Servant-Server.html#route" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:HasServer" class="caption collapser" onclick="toggleSection('i:HasServer')">Instances</p><div id="section.i:HasServer" class="show"><table><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a></td><td class="doc"><p>If you have a <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code> endpoint in your API,
25+ the handler for this endpoint is meant to delete
26+ a resource.</p><p>The code of the handler will, just like
27+ for <code><a href="Servant-API-Get.html#t:Get">Get</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code> and
28+ <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, run in <code>EitherT (Int, String) IO ()</code>.
29+ The <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message
30+ to be returned. You can use <code><a href="https://hackage.haskell.org/package/either-4.3.2/docs/Control-Monad-Trans-Either.html#v:left">left</a></code> to
31+ painlessly error out if the conditions for a successful deletion
32+ are not met.</p></td></tr><tr><td class="src"><a href="Servant-Server.html#t:HasServer">HasServer</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></td><td class="doc"><p>Just pass the request to the underlying application and serve its response.</p><p>Example:</p><pre>type MyApi = &quot;images&quot; :&gt; Raw
33+
34+server :: Server MyApi
35+server = serveDirectory &quot;/var/www/images&quot;</pre></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> result =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Get.html#t:Get">Get</a> result)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Get.html#t:Get">Get</a></code> endpoint,
36+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Post.html#t:Post">Post</a></code>
37+ and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
38+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
39+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
40+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
41+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
42+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
43+ yielding status code 200 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Post.html#t:Post">Post</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Post.html#t:Post">Post</a></code> endpoint,
44+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
45+ and <code><a href="Servant-API-Put.html#t:Put">Put</a></code>, the handler code runs in the
46+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
47+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
48+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
49+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
50+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
51+ yielding status code 201 along the way.</p></td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a> a =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Put.html#t:Put">Put</a> a)</td><td class="doc"><p>When implementing the handler for a <code><a href="Servant-API-Put.html#t:Put">Put</a></code> endpoint,
52+ just like for <code><a href="Servant-API-Delete.html#t:Delete">Delete</a></code>, <code><a href="Servant-API-Get.html#t:Get">Get</a></code>
53+ and <code><a href="Servant-API-Post.html#t:Post">Post</a></code>, the handler code runs in the
54+ <code>EitherT (Int, String) IO</code> monad, where the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Int.html#t:Int">Int</a></code> represents
55+ the status code and the <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></code> a message, returned in case of
56+ failure. You can quite handily use <code><a href="Control-Monad-Trans-EitherT.html#v:left">left</a></code>
57+ to quickly fail if some conditions are not met.</p><p>If successfully returning a value, we just require that its type has
58+ a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:ToJSON">ToJSON</a></code> instance and servant takes care of encoding it for you,
59+ yielding status code 200 along the way.</p></td></tr><tr><td class="src">(<a href="Servant-Server.html#t:HasServer">HasServer</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> b) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Alternative.html#t::-60--124--62-">(:&lt;|&gt;)</a> a b)</td><td class="doc"><p>A server for <code>a <code><a href="Servant-API-Alternative.html#t::-60--124--62-">:&lt;|&gt;</a></code> b</code> first tries to match the request again the route
60+ represented by <code>a</code> and if it fails tries <code>b</code>. You must provide a request
61+ handler for each route.</p><pre>type MyApi = &quot;books&quot; :&gt; Get [Book] -- GET /books
62+ :&lt;|&gt; &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book -- POST /books
63+
64+server :: Server MyApi
65+server = listAllBooks :&lt;|&gt; postBook
66+ where listAllBooks = ...
67+ postBook book = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> capture, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-Capture.html#t:Capture">Capture</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * capture a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code> in one of the endpoints for your API,
68+ this automatically requires your server-side handler to be a function
69+ that takes an argument of the type specified by the <code><a href="Servant-API-Capture.html#t:Capture">Capture</a></code>.
70+ This lets servant worry about getting it from the URL and turning
71+ it into a value of the type you specify.</p><p>You can control how it'll be converted from <code><a href="https://hackage.haskell.org/package/text-1.2.0.0/docs/Data-Text.html#t:Text">Text</a></code> to your type
72+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; Capture &quot;isbn&quot; Text :&gt; Get Book
73+
74+server :: Server MyApi
75+server = getBook
76+ where getBook :: Text -&gt; EitherT (Int, String) IO Book
77+ getBook isbn = ...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> sym) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryFlag">QueryFlag</a></code> &quot;published&quot;</code> in one of the endpoints for your API,
78+ this automatically requires your server-side handler to be a function
79+ that takes an argument of type <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a></code>.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryFlag &quot;published&quot; :&gt; Get [Book]
80+
81+server :: Server MyApi
82+server = getBooks
83+ where getBooks :: Bool -&gt; EitherT (Int, String) IO [Book]
84+ getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParams">QueryParams</a></code> &quot;authors&quot; Text</code> in one of the endpoints for your API,
85+ this automatically requires your server-side handler to be a function
86+ that takes an argument of type <code>[<code>Text</code>]</code>.</p><p>This lets servant worry about looking up 0 or more values in the query string
87+ associated to <code>authors</code> and turning each of them into a value of
88+ the type you specify.</p><p>You can control how the individual values are converted from <code>Text</code> to your type
89+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParams &quot;authors&quot; Text :&gt; Get [Book]
90+
91+server :: Server MyApi
92+server = getBooksBy
93+ where getBooksBy :: [Text] -&gt; EitherT (Int, String) IO [Book]
94+ getBooksBy authors = ...return all books by these authors...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> sym, <a href="Servant-Common-Text.html#t:FromText">FromText</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> * sym a) sublayout)</td><td class="doc"><p>If you use <code><code><a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a></code> &quot;author&quot; Text</code> in one of the endpoints for your API,
95+ this automatically requires your server-side handler to be a function
96+ that takes an argument of type <code><code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code> <code>Text</code></code>.</p><p>This lets servant worry about looking it up in the query string
97+ and turning it into a value of the type you specify, enclosed
98+ in <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#t:Maybe">Maybe</a></code>, because it may not be there and servant would then
99+ hand you <code><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Maybe.html#v:Nothing">Nothing</a></code>.</p><p>You can control how it'll be converted from <code>Text</code> to your type
100+ by simply providing an instance of <code><a href="Servant-Common-Text.html#t:FromText">FromText</a></code> for your type.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; QueryParam &quot;author&quot; Text :&gt; Get [Book]
101+
102+server :: Server MyApi
103+server = getBooksBy
104+ where getBooksBy :: Maybe Text -&gt; EitherT (Int, String) IO [Book]
105+ getBooksBy Nothing = ...return all books...
106+ getBooksBy (Just author) = ...return books by the given author...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a> a, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> * (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> * a) sublayout)</td><td class="doc"><p>If you use <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code> in one of the endpoints for your API,
107+ this automatically requires your server-side handler to be a function
108+ that takes an argument of the type specified by <code><a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a></code>.
109+ This lets servant worry about extracting it from the request and turning
110+ it into a value of the type you specify.</p><p>All it asks is for a <code><a href="https://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson-Types.html#t:FromJSON">FromJSON</a></code> instance.</p><p>Example:</p><pre>type MyApi = &quot;books&quot; :&gt; ReqBody Book :&gt; Post Book
111+
112+server :: Server MyApi
113+server = postBook
114+ where postBook :: Book -&gt; EitherT (Int, String) IO Book
115+ postBook book = ...insert into your db...</pre></td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> path, <a href="Servant-Server.html#t:HasServer">HasServer</a> sublayout) =&gt; <a href="Servant-Server.html#t:HasServer">HasServer</a> (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> path sublayout)</td><td class="doc"><p>Make sure the incoming request starts with <code>&quot;/path&quot;</code>, strip it and
116+ pass the rest of the request path to <code>sublayout</code>.</p></td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-Utils-Links.htmlnew file+23
@@ -0,0 +1,23 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.Links</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-Utils-Links.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Utils-Links.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Utils.Links</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>Type safe internal links.</p><p>Provides the function <code><a href="Servant-Utils-Links.html#v:mkLink">mkLink</a></code>:</p><pre> type API = Proxy (&quot;hello&quot; :&gt; Get Int
5+ :<a href="|">|</a> &quot;bye&quot; :&gt; QueryParam &quot;name&quot; String :&gt; Post Bool)
6+
7+ api :: API
8+ api = proxy
9+
10+ link1 :: Proxy (&quot;hello&quot; :&gt; Get Int)
11+ link1 = proxy
12+
13+ link2 :: Proxy (&quot;hello&quot; :&gt; Delete)
14+ link2 = proxy
15+
16+ mkLink link1 API -- typechecks, returns 'Link &quot;/hello&quot;'
17+
18+ mkLink link2 API -- doesn't typecheck
19+</pre><p>That is, <code><a href="Servant-Utils-Links.html#v:mkLink">mkLink</a></code> takes two arguments, a link proxy and a sitemap, and
20+ returns a <code><a href="Servant-Utils-Links.html#t:Link">Link</a></code>, but only typechecks if the link proxy is a valid link,
21+ and part of the sitemap.</p><p><strong>N.B.:</strong> <code><a href="Servant-Utils-Links.html#v:mkLink">mkLink</a></code> assumes a capture matches any string (without slashes).</p></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">type family</span> <a href="#t:Or">Or</a> a b</li><li class="src short"><span class="keyword">type family</span> <a href="#t:And">And</a> a b</li><li class="src short"><span class="keyword">type family</span> <a href="#t:IsElem">IsElem</a> a s</li><li class="src short"><span class="keyword">type family</span> <a href="#t:IsLink-39--39-">IsLink''</a> l</li><li class="src short"><span class="keyword">type family</span> <a href="#t:IsLink-39-">IsLink'</a> e</li><li class="src short"><span class="keyword">type family</span> <a href="#t:IsLink">IsLink</a> e</li><li class="src short"><span class="keyword">class</span> <a href="#t:ValidLinkIn">ValidLinkIn</a> f s <span class="keyword">where</span><ul class="subs"><li><a href="#v:mkLink">mkLink</a> :: f -&gt; s -&gt; <a href="Servant-Utils-Links.html#t:Link">Link</a></li></ul></li><li class="src short"><span class="keyword">data</span> <a href="#t:Link">Link</a> = <a href="#v:Link">Link</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></li><li class="src short"><span class="keyword">class</span> <a href="#t:VLinkHelper">VLinkHelper</a> f <span class="keyword">where</span><ul class="subs"><li><a href="#v:vlh">vlh</a> :: <span class="keyword">forall</span> proxy. proxy f -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></li></ul></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:Or" class="def">Or</a> a b <a href="src/Servant-Utils-Links.html#Or" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:Or">Or</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a> = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:Or">Or</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a> b = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:Or">Or</a> a <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a> = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:And" class="def">And</a> a b <a href="src/Servant-Utils-Links.html#And" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:And">And</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a> = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:And">And</a> a <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a> = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:And">And</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a> b = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:IsElem" class="def">IsElem</a> a s <a href="src/Servant-Utils-Links.html#IsElem" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> e (sa <a href="Servant-API-Alternative.html#t::-60--124--62-">:&lt;|&gt;</a> sb) = <a href="Servant-Utils-Links.html#t:Or">Or</a> (<a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> e sa) (<a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> e sb)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sa) (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sb) = <a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa sb</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sa) (<a href="Servant-API-Capture.html#t:Capture">Capture</a> x y <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sb) = <a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa sb</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa (<a href="Servant-API-ReqBody.html#t:ReqBody">ReqBody</a> x <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sb) = <a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa sb</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa (<a href="Servant-API-QueryParam.html#t:QueryParam">QueryParam</a> x y <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> sb) = <a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> sa sb</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> e e = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> e a = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:IsLink-39--39-" class="def">IsLink''</a> l <a href="src/Servant-Utils-Links.html#IsLink%27%27" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> <a href="Servant-API-Get.html#t:Get">Get</a> x) = <a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> e</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> <a href="Servant-API-Post.html#t:Post">Post</a> x) = <a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> e</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> <a href="Servant-API-Put.html#t:Put">Put</a> x) = <a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> e</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> (e <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> <a href="Servant-API-Delete.html#t:Delete">Delete</a>) = <a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> e</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> a = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:False">False</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:IsLink-39-" class="def">IsLink'</a> e <a href="src/Servant-Utils-Links.html#IsLink%27" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> (f :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a>) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">type family</span> <a name="t:IsLink" class="def">IsLink</a> e <a href="src/Servant-Utils-Links.html#IsLink" class="link">Source</a></p><div class="subs equations"><p class="caption">Equations</p><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:IsLink">IsLink</a> (a <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> b) = <a href="Servant-Utils-Links.html#t:Or">Or</a> (<a href="Servant-Utils-Links.html#t:And">And</a> (<a href="Servant-Utils-Links.html#t:IsLink-39-">IsLink'</a> a) (<a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> b)) (<a href="Servant-Utils-Links.html#t:IsLink-39--39-">IsLink''</a> (a <a href="Servant-API-Sub.html#t::-62-">:&gt;</a> b))</td><td class="doc empty">&nbsp;</td></tr></table></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:ValidLinkIn" class="def">ValidLinkIn</a> f s <span class="keyword">where</span> <a href="src/Servant-Utils-Links.html#ValidLinkIn" class="link">Source</a></p><div class="doc"><p>The 'ValidLinkIn f s' constraint holds when <code>s</code> is an API that
22+ contains <code>f</code>, and <code>f</code> is a link.</p></div><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:mkLink" class="def">mkLink</a> <a href="src/Servant-Utils-Links.html#mkLink" class="link">Source</a></p><div class="subs arguments"><p class="caption">Arguments</p><table><tr><td class="src">:: f</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src">-&gt; s</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src">-&gt; <a href="Servant-Utils-Links.html#t:Link">Link</a></td><td class="doc"><p>This function will only typecheck if <code>f</code>
23+ is an URI within <code>s</code></p></td></tr></table></div></div><div class="subs instances"><p id="control.i:ValidLinkIn" class="caption collapser" onclick="toggleSection('i:ValidLinkIn')">Instances</p><div id="section.i:ValidLinkIn" class="show"><table><tr><td class="src">((~) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> (<a href="Servant-Utils-Links.html#t:IsElem">IsElem</a> f s) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a>, (~) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#t:Bool">Bool</a> (<a href="Servant-Utils-Links.html#t:IsLink">IsLink</a> f) <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Bool.html#v:True">True</a>, <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * f) =&gt; <a href="Servant-Utils-Links.html#t:ValidLinkIn">ValidLinkIn</a> f s</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Link" class="def">Link</a> <a href="src/Servant-Utils-Links.html#Link" class="link">Source</a></p><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:Link" class="def">Link</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a></td><td class="doc empty">&nbsp;</td></tr></table></div><div class="subs instances"><p id="control.i:Link" class="caption collapser" onclick="toggleSection('i:Link')">Instances</p><div id="section.i:Link" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> <a href="Servant-Utils-Links.html#t:Link">Link</a></td><td class="doc empty">&nbsp;</td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">class</span> <a name="t:VLinkHelper" class="def">VLinkHelper</a> f <span class="keyword">where</span> <a href="src/Servant-Utils-Links.html#VLinkHelper" class="link">Source</a></p><div class="subs methods"><p class="caption">Methods</p><p class="src"><a name="v:vlh" class="def">vlh</a> :: <span class="keyword">forall</span> proxy. proxy f -&gt; <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-String.html#t:String">String</a> <a href="src/Servant-Utils-Links.html#vlh" class="link">Source</a></p></div><div class="subs instances"><p id="control.i:VLinkHelper" class="caption collapser" onclick="toggleSection('i:VLinkHelper')">Instances</p><div id="section.i:VLinkHelper" class="show"><table><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Get.html#t:Get">Get</a> x)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Post.html#t:Post">Post</a> x)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src">(<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:KnownSymbol">KnownSymbol</a> s, <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * e) =&gt; <a href="Servant-Utils-Links.html#t:VLinkHelper">VLinkHelper</a> * (<a href="Servant-API-Sub.html#t::-62-">(:&gt;)</a> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-TypeLits.html#t:Symbol">Symbol</a> s e)</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant-Utils-StaticFiles.htmlnew file+15
@@ -0,0 +1,15 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.StaticFiles</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant-Utils-StaticFiles.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant-Utils-StaticFiles.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant.Utils.StaticFiles</p></div><div id="description"><p class="caption">Description</p><div class="doc"><p>This module defines a sever-side handler that lets you serve static files.</p><ul><li><code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code> lets you serve anything that lives under a particular
5+ directory on your filesystem.</li></ul></div></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><a href="#v:serveDirectory">serveDirectory</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:FilePath">FilePath</a> -&gt; <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="top"><p class="src"><a name="v:serveDirectory" class="def">serveDirectory</a> :: <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO.html#t:FilePath">FilePath</a> -&gt; <a href="Servant-Server.html#t:Server">Server</a> <a href="Servant-API-Raw.html#t:Raw">Raw</a> <a href="src/Servant-Utils-StaticFiles.html#serveDirectory" class="link">Source</a></p><div class="doc"><p>Serve anything under the specified directory as a <code><a href="Servant-API-Raw.html#t:Raw">Raw</a></code> endpoint.</p><pre>type MyApi = &quot;static&quot; :&gt; Raw
6+
7+server :: Server MyApi
8+server = serveDirectory &quot;/var/www&quot;
9+</pre><p>would capture any request to <code>/static/&lt;something&gt;</code> and look for
10+ <code>&lt;something&gt;</code> under <code>/var/www</code>.</p><p>It will do its best to guess the MIME type for that file, based on the extension,
11+ and send an appropriate <em>Content-Type</em> header if possible.</p><p>If your goal is to serve HTML, CSS and Javascript files that use the rest of the API
12+ as a webapp backend, you will most likely not want the static files to be hidden
13+ behind a <em>/static/</em> prefix. In that case, remember to put the <code><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">serveDirectory</a></code>
14+ handler in the last position, because <em>servant</em> will try to match the handlers
15+ in order.</p></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
Servant.htmlnew file+6
@@ -0,0 +1,6 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();setSynopsis("mini_Servant.html");};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Servant.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>None</td></tr><tr><th>Language</th><td>Haskell2010</td></tr></table><p class="caption">Servant</p></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short">module <a href="Servant-API.html">Servant.API</a></li><li class="src short">module <a href="Servant-Server.html">Servant.Server</a></li><li class="src short">module <a href="Servant-Common-Text.html">Servant.Common.Text</a></li><li class="src short">module <a href="Servant-QQ.html">Servant.QQ</a></li><li class="src short">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></li><li class="src short">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></li><li class="src short"><span class="keyword">data</span> <a href="#t:Proxy">Proxy</a> t :: k -&gt; * = <a href="#v:Proxy">Proxy</a></li></ul></div><div id="interface"><h1>Documentation</h1><div class="doc"><p>This module and its submodules can be used to define servant APIs. Note
5+ that these API definitions don't directly implement a server (or anything
6+ else).</p></div><div class="top"><p class="src">module <a href="Servant-API.html">Servant.API</a></p></div><div class="doc"><p>For implementing servers for servant APIs.</p></div><div class="top"><p class="src">module <a href="Servant-Server.html">Servant.Server</a></p></div><div class="doc"><p>Using your types in request paths and query string parameters</p></div><div class="top"><p class="src">module <a href="Servant-Common-Text.html">Servant.Common.Text</a></p></div><div class="doc"><p>Utilities on top of the servant core</p></div><div class="top"><p class="src">module <a href="Servant-QQ.html">Servant.QQ</a></p></div><div class="top"><p class="src">module <a href="Servant-Utils-Links.html">Servant.Utils.Links</a></p></div><div class="top"><p class="src">module <a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></p></div><div class="doc"><p>Useful re-exports</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:Proxy" class="def">Proxy</a> t :: k -&gt; *</p><div class="doc"><p>A concrete, poly-kinded proxy type</p></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:Proxy" class="def">Proxy</a></td><td class="doc empty">&nbsp;</td></tr></table></div><div class="subs instances"><p id="control.i:Proxy" class="caption collapser" onclick="toggleSection('i:Proxy')">Instances</p><div id="section.i:Proxy" class="show"><table><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Monad.html#t:Monad">Monad</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Monad.html#t:Functor">Functor</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Control-Applicative.html#t:Applicative">Applicative</a> (<a href="Servant.html#t:Proxy">Proxy</a> *)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Bounded">Bounded</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#t:Enum">Enum</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Eq.html#t:Eq">Eq</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Ord.html#t:Ord">Ord</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Read.html#t:Read">Read</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Text-Show.html#t:Show">Show</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Ix.html#t:Ix">Ix</a> (<a href="Servant.html#t:Proxy">Proxy</a> k s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:Generic">Generic</a> (<a href="Servant.html#t:Proxy">Proxy</a> * t)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Monoid.html#t:Monoid">Monoid</a> (<a href="Servant.html#t:Proxy">Proxy</a> * s)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Typeable-Internal.html#t:Typeable">Typeable</a> (k -&gt; *) (<a href="Servant.html#t:Proxy">Proxy</a> k)</td><td class="doc empty">&nbsp;</td></tr><tr><td class="src"><span class="keyword">type</span> <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:Rep">Rep</a> (<a href="Servant.html#t:Proxy">Proxy</a> k t) = <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:D1">D1</a> D1Proxy (<a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:C1">C1</a> C1_0Proxy <a href="https://hackage.haskell.org/package/base-4.7.0.1/docs/GHC-Generics.html#t:U1">U1</a>)</td><td class="doc empty">&nbsp;</td></tr></table></div></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
doc-index.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>servant-0.2 (Index)</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="index"><p class="caption">Index</p><table><tr><td class="src">:&lt;|&gt;</td><td>&nbsp;</td></tr><tr><td class="alt">1 (Type/Class)</td><td class="module"><a href="Servant-API-Alternative.html#t::-60--124--62-">Servant.API.Alternative</a>, Servant.API, Servant</td></tr><tr><td class="alt">2 (Data Constructor)</td><td class="module"><a href="Servant-API-Alternative.html#v::-60--124--62-">Servant.API.Alternative</a>, Servant.API, Servant</td></tr><tr><td class="src">:&gt;</td><td>&nbsp;</td></tr><tr><td class="alt">1 (Type/Class)</td><td class="module"><a href="Servant-API-Sub.html#t::-62-">Servant.API.Sub</a>, Servant.API, Servant</td></tr><tr><td class="alt">2 (Data Constructor)</td><td class="module"><a href="Servant-API-Sub.html#v::-62-">Servant.API.Sub</a>, Servant.API, Servant</td></tr><tr><td class="src">&gt;:</td><td class="module"><a href="Servant-QQ.html#v:-62-:">Servant.QQ</a>, Servant</td></tr><tr><td class="src">And</td><td class="module"><a href="Servant-Utils-Links.html#t:And">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">blockComment</td><td class="module"><a href="Servant-QQ.html#v:blockComment">Servant.QQ</a>, Servant</td></tr><tr><td class="src">Capture</td><td class="module"><a href="Servant-API-Capture.html#t:Capture">Servant.API.Capture</a>, Servant.API, Servant</td></tr><tr><td class="src">capture</td><td class="module"><a href="Servant-QQ.html#v:capture">Servant.QQ</a>, Servant</td></tr><tr><td class="src">conj</td><td class="module"><a href="Servant-QQ.html#v:conj">Servant.QQ</a>, Servant</td></tr><tr><td class="src">Delete</td><td class="module"><a href="Servant-API-Delete.html#t:Delete">Servant.API.Delete</a>, Servant.API, Servant</td></tr><tr><td class="src">delete</td><td class="module"><a href="Servant-QQ.html#v:delete">Servant.QQ</a>, Servant</td></tr><tr><td class="src">eol</td><td class="module"><a href="Servant-QQ.html#v:eol">Servant.QQ</a>, Servant</td></tr><tr><td class="src">eols</td><td class="module"><a href="Servant-QQ.html#v:eols">Servant.QQ</a>, Servant</td></tr><tr><td class="src">ExpSYM</td><td class="module"><a href="Servant-QQ.html#t:ExpSYM">Servant.QQ</a>, Servant</td></tr><tr><td class="src">failWith</td><td class="module"><a href="Servant-Server.html#v:failWith">Servant.Server</a>, Servant</td></tr><tr><td class="src">FromText</td><td class="module"><a href="Servant-Common-Text.html#t:FromText">Servant.Common.Text</a>, Servant</td></tr><tr><td class="src">fromText</td><td class="module"><a href="Servant-Common-Text.html#v:fromText">Servant.Common.Text</a>, Servant</td></tr><tr><td class="src">Get</td><td class="module"><a href="Servant-API-Get.html#t:Get">Servant.API.Get</a>, Servant.API, Servant</td></tr><tr><td class="src">get</td><td class="module"><a href="Servant-QQ.html#v:get">Servant.QQ</a>, Servant</td></tr><tr><td class="src">HasServer</td><td class="module"><a href="Servant-Server.html#t:HasServer">Servant.Server</a>, Servant</td></tr><tr><td class="src">inlineComment</td><td class="module"><a href="Servant-QQ.html#v:inlineComment">Servant.QQ</a>, Servant</td></tr><tr><td class="src">InvalidBody</td><td class="module"><a href="Servant-Server.html#v:InvalidBody">Servant.Server</a>, Servant</td></tr><tr><td class="src">IsElem</td><td class="module"><a href="Servant-Utils-Links.html#t:IsElem">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">IsLink</td><td class="module"><a href="Servant-Utils-Links.html#t:IsLink">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">IsLink'</td><td class="module"><a href="Servant-Utils-Links.html#t:IsLink-39-">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">IsLink''</td><td class="module"><a href="Servant-Utils-Links.html#t:IsLink-39--39-">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">isMismatch</td><td class="module"><a href="Servant-Server.html#v:isMismatch">Servant.Server</a>, Servant</td></tr><tr><td class="src">Link</td><td>&nbsp;</td></tr><tr><td class="alt">1 (Type/Class)</td><td class="module"><a href="Servant-Utils-Links.html#t:Link">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="alt">2 (Data Constructor)</td><td class="module"><a href="Servant-Utils-Links.html#v:Link">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">lit</td><td class="module"><a href="Servant-QQ.html#v:lit">Servant.QQ</a>, Servant</td></tr><tr><td class="src">mkLink</td><td class="module"><a href="Servant-Utils-Links.html#v:mkLink">Servant.Utils.Links</a>, Servant.API, Servant</td></tr><tr><td class="src">NotFound</td><td class="module"><a href="Servant-Server.html#v:NotFound">Servant.Server</a>, Servant</td></tr><tr><td class="src">Or</td><td class="module"><a href="Servant-Utils-Links.html#t:Or">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">parseAll</td><td class="module"><a href="Servant-QQ.html#v:parseAll">Servant.QQ</a>, Servant</td></tr><tr><td class="src">parseEntry</td><td class="module"><a href="Servant-QQ.html#v:parseEntry">Servant.QQ</a>, Servant</td></tr><tr><td class="src">parseMethod</td><td class="module"><a href="Servant-QQ.html#v:parseMethod">Servant.QQ</a>, Servant</td></tr><tr><td class="src">parseTyp</td><td class="module"><a href="Servant-QQ.html#v:parseTyp">Servant.QQ</a>, Servant</td></tr><tr><td class="src">parseUrl</td><td class="module"><a href="Servant-QQ.html#v:parseUrl">Servant.QQ</a>, Servant</td></tr><tr><td class="src">parseUrlSegment</td><td class="module"><a href="Servant-QQ.html#v:parseUrlSegment">Servant.QQ</a>, Servant</td></tr><tr><td class="src">Post</td><td class="module"><a href="Servant-API-Post.html#t:Post">Servant.API.Post</a>, Servant.API, Servant</td></tr><tr><td class="src">post</td><td class="module"><a href="Servant-QQ.html#v:post">Servant.QQ</a>, Servant</td></tr><tr><td class="src">Proxy</td><td>&nbsp;</td></tr><tr><td class="alt">1 (Data Constructor)</td><td class="module"><a href="Servant.html#v:Proxy">Servant</a></td></tr><tr><td class="alt">2 (Type/Class)</td><td class="module"><a href="Servant.html#t:Proxy">Servant</a></td></tr><tr><td class="src">Put</td><td class="module"><a href="Servant-API-Put.html#t:Put">Servant.API.Put</a>, Servant.API, Servant</td></tr><tr><td class="src">put</td><td class="module"><a href="Servant-QQ.html#v:put">Servant.QQ</a>, Servant</td></tr><tr><td class="src">QueryFlag</td><td class="module"><a href="Servant-API-QueryParam.html#t:QueryFlag">Servant.API.QueryParam</a>, Servant.API, Servant</td></tr><tr><td class="src">QueryParam</td><td class="module"><a href="Servant-API-QueryParam.html#t:QueryParam">Servant.API.QueryParam</a>, Servant.API, Servant</td></tr><tr><td class="src">queryParam</td><td class="module"><a href="Servant-QQ.html#v:queryParam">Servant.QQ</a>, Servant</td></tr><tr><td class="src">QueryParams</td><td class="module"><a href="Servant-API-QueryParam.html#t:QueryParams">Servant.API.QueryParam</a>, Servant.API, Servant</td></tr><tr><td class="src">Raw</td><td class="module"><a href="Servant-API-Raw.html#t:Raw">Servant.API.Raw</a>, Servant.API, Servant</td></tr><tr><td class="src">ReqArgVal</td><td class="module"><a href="Servant-QQ.html#v:ReqArgVal">Servant.QQ</a>, Servant</td></tr><tr><td class="src">ReqBody</td><td class="module"><a href="Servant-API-ReqBody.html#t:ReqBody">Servant.API.ReqBody</a>, Servant.API, Servant</td></tr><tr><td class="src">reqBody</td><td class="module"><a href="Servant-QQ.html#v:reqBody">Servant.QQ</a>, Servant</td></tr><tr><td class="src">route</td><td class="module"><a href="Servant-Server.html#v:route">Servant.Server</a>, Servant</td></tr><tr><td class="src">RouteMismatch</td><td class="module"><a href="Servant-Server.html#t:RouteMismatch">Servant.Server</a>, Servant</td></tr><tr><td class="src">RouteResult</td><td class="module"><a href="Servant-Server.html#t:RouteResult">Servant.Server</a>, Servant</td></tr><tr><td class="src">routeResult</td><td class="module"><a href="Servant-Server.html#v:routeResult">Servant.Server</a>, Servant</td></tr><tr><td class="src">RoutingApplication</td><td class="module"><a href="Servant-Server.html#t:RoutingApplication">Servant.Server</a>, Servant</td></tr><tr><td class="src">RR</td><td class="module"><a href="Servant-Server.html#v:RR">Servant.Server</a>, Servant</td></tr><tr><td class="src">serve</td><td class="module"><a href="Servant-Server.html#v:serve">Servant.Server</a>, Servant</td></tr><tr><td class="src">serveDirectory</td><td class="module"><a href="Servant-Utils-StaticFiles.html#v:serveDirectory">Servant.Utils.StaticFiles</a>, Servant.API, Servant</td></tr><tr><td class="src">Server</td><td class="module"><a href="Servant-Server.html#t:Server">Servant.Server</a>, Servant</td></tr><tr><td class="src">sitemap</td><td class="module"><a href="Servant-QQ.html#v:sitemap">Servant.QQ</a>, Servant.API, Servant</td></tr><tr><td class="src">succeedWith</td><td class="module"><a href="Servant-Server.html#v:succeedWith">Servant.Server</a>, Servant</td></tr><tr><td class="src">toApplication</td><td class="module"><a href="Servant-Server.html#v:toApplication">Servant.Server</a>, Servant</td></tr><tr><td class="src">ToText</td><td class="module"><a href="Servant-Common-Text.html#t:ToText">Servant.Common.Text</a>, Servant</td></tr><tr><td class="src">toText</td><td class="module"><a href="Servant-Common-Text.html#v:toText">Servant.Common.Text</a>, Servant</td></tr><tr><td class="src">Typ</td><td class="module"><a href="Servant-QQ.html#t:Typ">Servant.QQ</a>, Servant</td></tr><tr><td class="src">Val</td><td class="module"><a href="Servant-QQ.html#v:Val">Servant.QQ</a>, Servant</td></tr><tr><td class="src">ValidLinkIn</td><td class="module"><a href="Servant-Utils-Links.html#t:ValidLinkIn">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">vlh</td><td class="module"><a href="Servant-Utils-Links.html#v:vlh">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">VLinkHelper</td><td class="module"><a href="Servant-Utils-Links.html#t:VLinkHelper">Servant.Utils.Links</a>, Servant</td></tr><tr><td class="src">WrongMethod</td><td class="module"><a href="Servant-Server.html#v:WrongMethod">Servant.Server</a>, Servant</td></tr></table></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
frames.htmlnew file+30
@@ -0,0 +1,30 @@
1+<!DOCTYPE html
2+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
3+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
4+<html xmlns="http://www.w3.org/1999/xhtml">
5+<head>
6+<title></title>
7+<script src="haddock-util.js" type="text/javascript"></script>
8+<script type="text/javascript"><!--
9+/*
10+
11+ The synopsis frame needs to be updated using javascript, so we hide
12+ it by default and only show it if javascript is enabled.
13+
14+ TODO: provide some means to disable it.
15+*/
16+function load() {
17+ var d = document.getElementById("inner-fs");
18+ d.rows = "50%,50%";
19+ postReframe();
20+}
21+--></script>
22+</head>
23+<frameset id="outer-fs" cols="25%,75%" onload="load()">
24+ <frameset id="inner-fs" rows="100%,0%">
25+ <frame src="index-frames.html" name="modules" />
26+ <frame src="" name="synopsis" />
27+ </frameset>
28+ <frame src="index.html" name="main" />
29+</frameset>
30+</html>
haddock-util.jsnew file+344
@@ -0,0 +1,344 @@
1+// Haddock JavaScript utilities
2+
3+var rspace = /\s\s+/g,
4+ rtrim = /^\s+|\s+$/g;
5+
6+function spaced(s) { return (" " + s + " ").replace(rspace, " "); }
7+function trim(s) { return s.replace(rtrim, ""); }
8+
9+function hasClass(elem, value) {
10+ var className = spaced(elem.className || "");
11+ return className.indexOf( " " + value + " " ) >= 0;
12+}
13+
14+function addClass(elem, value) {
15+ var className = spaced(elem.className || "");
16+ if ( className.indexOf( " " + value + " " ) < 0 ) {
17+ elem.className = trim(className + " " + value);
18+ }
19+}
20+
21+function removeClass(elem, value) {
22+ var className = spaced(elem.className || "");
23+ className = className.replace(" " + value + " ", " ");
24+ elem.className = trim(className);
25+}
26+
27+function toggleClass(elem, valueOn, valueOff, bool) {
28+ if (bool == null) { bool = ! hasClass(elem, valueOn); }
29+ if (bool) {
30+ removeClass(elem, valueOff);
31+ addClass(elem, valueOn);
32+ }
33+ else {
34+ removeClass(elem, valueOn);
35+ addClass(elem, valueOff);
36+ }
37+ return bool;
38+}
39+
40+
41+function makeClassToggle(valueOn, valueOff)
42+{
43+ return function(elem, bool) {
44+ return toggleClass(elem, valueOn, valueOff, bool);
45+ }
46+}
47+
48+toggleShow = makeClassToggle("show", "hide");
49+toggleCollapser = makeClassToggle("collapser", "expander");
50+
51+function toggleSection(id)
52+{
53+ var b = toggleShow(document.getElementById("section." + id));
54+ toggleCollapser(document.getElementById("control." + id), b);
55+ rememberCollapsed(id, b);
56+ return b;
57+}
58+
59+var collapsed = {};
60+function rememberCollapsed(id, b)
61+{
62+ if(b)
63+ delete collapsed[id]
64+ else
65+ collapsed[id] = null;
66+
67+ var sections = [];
68+ for(var i in collapsed)
69+ {
70+ if(collapsed.hasOwnProperty(i))
71+ sections.push(i);
72+ }
73+ // cookie specific to this page; don't use setCookie which sets path=/
74+ document.cookie = "collapsed=" + escape(sections.join('+'));
75+}
76+
77+function restoreCollapsed()
78+{
79+ var cookie = getCookie("collapsed");
80+ if(!cookie)
81+ return;
82+
83+ var ids = cookie.split('+');
84+ for(var i in ids)
85+ {
86+ if(document.getElementById("section." + ids[i]))
87+ toggleSection(ids[i]);
88+ }
89+}
90+
91+function setCookie(name, value) {
92+ document.cookie = name + "=" + escape(value) + ";path=/;";
93+}
94+
95+function clearCookie(name) {
96+ document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
97+}
98+
99+function getCookie(name) {
100+ var nameEQ = name + "=";
101+ var ca = document.cookie.split(';');
102+ for(var i=0;i < ca.length;i++) {
103+ var c = ca[i];
104+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
105+ if (c.indexOf(nameEQ) == 0) {
106+ return unescape(c.substring(nameEQ.length,c.length));
107+ }
108+ }
109+ return null;
110+}
111+
112+
113+
114+var max_results = 75; // 50 is not enough to search for map in the base libraries
115+var shown_range = null;
116+var last_search = null;
117+
118+function quick_search()
119+{
120+ perform_search(false);
121+}
122+
123+function full_search()
124+{
125+ perform_search(true);
126+}
127+
128+
129+function perform_search(full)
130+{
131+ var text = document.getElementById("searchbox").value.toLowerCase();
132+ if (text == last_search && !full) return;
133+ last_search = text;
134+
135+ var table = document.getElementById("indexlist");
136+ var status = document.getElementById("searchmsg");
137+ var children = table.firstChild.childNodes;
138+
139+ // first figure out the first node with the prefix
140+ var first = bisect(-1);
141+ var last = (first == -1 ? -1 : bisect(1));
142+
143+ if (first == -1)
144+ {
145+ table.className = "";
146+ status.innerHTML = "No results found, displaying all";
147+ }
148+ else if (first == 0 && last == children.length - 1)
149+ {
150+ table.className = "";
151+ status.innerHTML = "";
152+ }
153+ else if (last - first >= max_results && !full)
154+ {
155+ table.className = "";
156+ status.innerHTML = "More than " + max_results + ", press Search to display";
157+ }
158+ else
159+ {
160+ // decide what you need to clear/show
161+ if (shown_range)
162+ setclass(shown_range[0], shown_range[1], "indexrow");
163+ setclass(first, last, "indexshow");
164+ shown_range = [first, last];
165+ table.className = "indexsearch";
166+ status.innerHTML = "";
167+ }
168+
169+
170+ function setclass(first, last, status)
171+ {
172+ for (var i = first; i <= last; i++)
173+ {
174+ children[i].className = status;
175+ }
176+ }
177+
178+
179+ // do a binary search, treating 0 as ...
180+ // return either -1 (no 0's found) or location of most far match
181+ function bisect(dir)
182+ {
183+ var first = 0, finish = children.length - 1;
184+ var mid, success = false;
185+
186+ while (finish - first > 3)
187+ {
188+ mid = Math.floor((finish + first) / 2);
189+
190+ var i = checkitem(mid);
191+ if (i == 0) i = dir;
192+ if (i == -1)
193+ finish = mid;
194+ else
195+ first = mid;
196+ }
197+ var a = (dir == 1 ? first : finish);
198+ var b = (dir == 1 ? finish : first);
199+ for (var i = b; i != a - dir; i -= dir)
200+ {
201+ if (checkitem(i) == 0) return i;
202+ }
203+ return -1;
204+ }
205+
206+
207+ // from an index, decide what the result is
208+ // 0 = match, -1 is lower, 1 is higher
209+ function checkitem(i)
210+ {
211+ var s = getitem(i).toLowerCase().substr(0, text.length);
212+ if (s == text) return 0;
213+ else return (s > text ? -1 : 1);
214+ }
215+
216+
217+ // from an index, get its string
218+ // this abstracts over alternates
219+ function getitem(i)
220+ {
221+ for ( ; i >= 0; i--)
222+ {
223+ var s = children[i].firstChild.firstChild.data;
224+ if (s.indexOf(' ') == -1)
225+ return s;
226+ }
227+ return ""; // should never be reached
228+ }
229+}
230+
231+function setSynopsis(filename) {
232+ if (parent.window.synopsis) {
233+ if (parent.window.synopsis.location.replace) {
234+ // In Firefox this avoids adding the change to the history.
235+ parent.window.synopsis.location.replace(filename);
236+ } else {
237+ parent.window.synopsis.location = filename;
238+ }
239+ }
240+}
241+
242+function addMenuItem(html) {
243+ var menu = document.getElementById("page-menu");
244+ if (menu) {
245+ var btn = menu.firstChild.cloneNode(false);
246+ btn.innerHTML = html;
247+ menu.appendChild(btn);
248+ }
249+}
250+
251+function adjustForFrames() {
252+ var bodyCls;
253+
254+ if (parent.location.href == window.location.href) {
255+ // not in frames, so add Frames button
256+ addMenuItem("<a href='#' onclick='reframe();return true;'>Frames</a>");
257+ bodyCls = "no-frame";
258+ }
259+ else {
260+ bodyCls = "in-frame";
261+ }
262+ addClass(document.body, bodyCls);
263+}
264+
265+function reframe() {
266+ setCookie("haddock-reframe", document.URL);
267+ window.location = "frames.html";
268+}
269+
270+function postReframe() {
271+ var s = getCookie("haddock-reframe");
272+ if (s) {
273+ parent.window.main.location = s;
274+ clearCookie("haddock-reframe");
275+ }
276+}
277+
278+function styles() {
279+ var i, a, es = document.getElementsByTagName("link"), rs = [];
280+ for (i = 0; a = es[i]; i++) {
281+ if(a.rel.indexOf("style") != -1 && a.title) {
282+ rs.push(a);
283+ }
284+ }
285+ return rs;
286+}
287+
288+function addStyleMenu() {
289+ var as = styles();
290+ var i, a, btns = "";
291+ for(i=0; a = as[i]; i++) {
292+ btns += "<li><a href='#' onclick=\"setActiveStyleSheet('"
293+ + a.title + "'); return false;\">"
294+ + a.title + "</a></li>"
295+ }
296+ if (as.length > 1) {
297+ var h = "<div id='style-menu-holder'>"
298+ + "<a href='#' onclick='styleMenu(); return false;'>Style &#9662;</a>"
299+ + "<ul id='style-menu' class='hide'>" + btns + "</ul>"
300+ + "</div>";
301+ addMenuItem(h);
302+ }
303+}
304+
305+function setActiveStyleSheet(title) {
306+ var as = styles();
307+ var i, a, found;
308+ for(i=0; a = as[i]; i++) {
309+ a.disabled = true;
310+ // need to do this always, some browsers are edge triggered
311+ if(a.title == title) {
312+ found = a;
313+ }
314+ }
315+ if (found) {
316+ found.disabled = false;
317+ setCookie("haddock-style", title);
318+ }
319+ else {
320+ as[0].disabled = false;
321+ clearCookie("haddock-style");
322+ }
323+ styleMenu(false);
324+}
325+
326+function resetStyle() {
327+ var s = getCookie("haddock-style");
328+ if (s) setActiveStyleSheet(s);
329+}
330+
331+
332+function styleMenu(show) {
333+ var m = document.getElementById('style-menu');
334+ if (m) toggleShow(m, show);
335+}
336+
337+
338+function pageLoad() {
339+ addStyleMenu();
340+ adjustForFrames();
341+ resetStyle();
342+ restoreCollapsed();
343+}
344+
hslogo-16.pngnew file

Binary file not shown.

index-frames.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>servant-0.2</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-list"><p class="caption">Modules</p><ul><li class="module"><a href="Servant.html" target="main">Servant</a></li><li class="module"><a href="Servant-API.html" target="main">Servant.API</a></li><li class="module"><a href="Servant-API-Alternative.html" target="main">Servant.API.Alternative</a></li><li class="module"><a href="Servant-API-Capture.html" target="main">Servant.API.Capture</a></li><li class="module"><a href="Servant-API-Delete.html" target="main">Servant.API.Delete</a></li><li class="module"><a href="Servant-API-Get.html" target="main">Servant.API.Get</a></li><li class="module"><a href="Servant-API-Post.html" target="main">Servant.API.Post</a></li><li class="module"><a href="Servant-API-Put.html" target="main">Servant.API.Put</a></li><li class="module"><a href="Servant-API-QueryParam.html" target="main">Servant.API.QueryParam</a></li><li class="module"><a href="Servant-API-Raw.html" target="main">Servant.API.Raw</a></li><li class="module"><a href="Servant-API-ReqBody.html" target="main">Servant.API.ReqBody</a></li><li class="module"><a href="Servant-API-Sub.html" target="main">Servant.API.Sub</a></li><li class="module"><a href="Servant-Common-Text.html" target="main">Servant.Common.Text</a></li><li class="module"><a href="Servant-QQ.html" target="main">Servant.QQ</a></li><li class="module"><a href="Servant-Server.html" target="main">Servant.Server</a></li><li class="module"><a href="Servant-Utils-Links.html" target="main">Servant.Utils.Links</a></li><li class="module"><a href="Servant-Utils-StaticFiles.html" target="main">Servant.Utils.StaticFiles</a></li></ul></div></body></html>
index.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>servant-0.2</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">servant-0.2</p></div><div id="content"><div id="description"><h1>servant-0.2</h1><div class="doc empty">&nbsp;</div></div><div id="module-list"><p class="caption">Modules</p><ul><li><span class="module"><span id="control.n.1" class="collapser" onclick="toggleSection('n.1')">&nbsp;</span><a href="Servant.html">Servant</a></span><ul id="section.n.1" class="show"><li><span class="module"><span id="control.n.1.1" class="collapser" onclick="toggleSection('n.1.1')">&nbsp;</span><a href="Servant-API.html">Servant.API</a></span><ul id="section.n.1.1" class="show"><li><span class="module"><a href="Servant-API-Alternative.html">Servant.API.Alternative</a></span></li><li><span class="module"><a href="Servant-API-Capture.html">Servant.API.Capture</a></span></li><li><span class="module"><a href="Servant-API-Delete.html">Servant.API.Delete</a></span></li><li><span class="module"><a href="Servant-API-Get.html">Servant.API.Get</a></span></li><li><span class="module"><a href="Servant-API-Post.html">Servant.API.Post</a></span></li><li><span class="module"><a href="Servant-API-Put.html">Servant.API.Put</a></span></li><li><span class="module"><a href="Servant-API-QueryParam.html">Servant.API.QueryParam</a></span></li><li><span class="module"><a href="Servant-API-Raw.html">Servant.API.Raw</a></span></li><li><span class="module"><a href="Servant-API-ReqBody.html">Servant.API.ReqBody</a></span></li><li><span class="module"><a href="Servant-API-Sub.html">Servant.API.Sub</a></span></li></ul></li><li><span id="control.n.1.2" class="module collapser" onclick="toggleSection('n.1.2')">Common</span><ul id="section.n.1.2" class="show"><li><span class="module"><a href="Servant-Common-Text.html">Servant.Common.Text</a></span></li></ul></li><li><span class="module"><a href="Servant-QQ.html">Servant.QQ</a></span></li><li><span class="module"><a href="Servant-Server.html">Servant.Server</a></span></li><li><span id="control.n.1.5" class="module collapser" onclick="toggleSection('n.1.5')">Utils</span><ul id="section.n.1.5" class="show"><li><span class="module"><a href="Servant-Utils-Links.html">Servant.Utils.Links</a></span></li><li><span class="module"><a href="Servant-Utils-StaticFiles.html">Servant.Utils.StaticFiles</a></span></li></ul></li></ul></li></ul></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.15.0</p></div></body></html>
mini_Servant-API-Alternative.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Alternative</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Alternative</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> a <a href="Servant-API-Alternative.html#t::-60--124--62-" target="main">:&lt;|&gt;</a> b</p></div></div></body></html>
mini_Servant-API-Capture.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Capture</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Capture</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Capture.html#t:Capture" target="main">Capture</a> sym a</p></div></div></body></html>
mini_Servant-API-Delete.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Delete</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Delete</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Delete.html#t:Delete" target="main">Delete</a></p></div></div></body></html>
mini_Servant-API-Get.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Get</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Get</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Get.html#t:Get" target="main">Get</a> a</p></div></div></body></html>
mini_Servant-API-Post.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Post</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Post</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Post.html#t:Post" target="main">Post</a> a</p></div></div></body></html>
mini_Servant-API-Put.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Put</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Put</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Put.html#t:Put" target="main">Put</a> a</p></div></div></body></html>
mini_Servant-API-QueryParam.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.QueryParam</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.QueryParam</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryParam" target="main">QueryParam</a> sym a</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryParams" target="main">QueryParams</a> sym a</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-QueryParam.html#t:QueryFlag" target="main">QueryFlag</a> sym</p></div></div></body></html>
mini_Servant-API-Raw.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Raw</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Raw</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-Raw.html#t:Raw" target="main">Raw</a></p></div></div></body></html>
mini_Servant-API-ReqBody.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.ReqBody</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.ReqBody</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-API-ReqBody.html#t:ReqBody" target="main">ReqBody</a> a</p></div></div></body></html>
mini_Servant-API-Sub.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API.Sub</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API.Sub</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> path <a href="Servant-API-Sub.html#t::-62-" target="main">:&gt;</a> a</p></div></div></body></html>
mini_Servant-API.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.API</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.API</p></div><div id="interface"><h1>Combinators</h1><h1>Accessing information from the request</h1><h1>Actual endpoints, distinguished by HTTP method</h1><h1>Untyped endpoints</h1><h1>Utilities</h1></div></body></html>
mini_Servant-Common-Text.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Common.Text</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Common.Text</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Common-Text.html#t:FromText" target="main">FromText</a> a</p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Common-Text.html#t:ToText" target="main">ToText</a> a</p></div></div></body></html>
mini_Servant-QQ.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.QQ</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.QQ</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-QQ.html#t:ExpSYM" target="main">ExpSYM</a> repr' repr</p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:-62-:" target="main">(&gt;:)</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseMethod" target="main">parseMethod</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseUrlSegment" target="main">parseUrlSegment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseUrl" target="main">parseUrl</a></p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-QQ.html#t:Typ" target="main">Typ</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseTyp" target="main">parseTyp</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseEntry" target="main">parseEntry</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:blockComment" target="main">blockComment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:inlineComment" target="main">inlineComment</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:eol" target="main">eol</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:eols" target="main">eols</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:parseAll" target="main">parseAll</a></p></div><div class="top"><p class="src"><a href="Servant-QQ.html#v:sitemap" target="main">sitemap</a></p></div></div></body></html>
mini_Servant-Server.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Server</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Server</p></div><div id="interface"><h1>Implementing Servers</h1><div class="top"><p class="src"><a href="Servant-Server.html#v:serve" target="main">serve</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:toApplication" target="main">toApplication</a></p></div><h1>Route mismatch</h1><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Server.html#t:RouteMismatch" target="main">RouteMismatch</a></p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Server.html#t:RouteResult" target="main">RouteResult</a> a</p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:failWith" target="main">failWith</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:succeedWith" target="main">succeedWith</a></p></div><div class="top"><p class="src"><a href="Servant-Server.html#v:isMismatch" target="main">isMismatch</a></p></div><div class="top"><p class="src"><span class="keyword">type</span> <a href="Servant-Server.html#t:RoutingApplication" target="main">RoutingApplication</a></p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Server.html#t:HasServer" target="main">HasServer</a> layout</p></div></div></body></html>
mini_Servant-Utils-Links.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.Links</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Utils.Links</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:Or">Or</a> a b</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:And">And</a> a b</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsElem">IsElem</a> a s</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink-39--39-">IsLink''</a> l</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink-39-">IsLink'</a> e</p></div><div class="top"><p class="src"><span class="keyword">type family</span> <a href="#t:IsLink">IsLink</a> e</p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Utils-Links.html#t:ValidLinkIn" target="main">ValidLinkIn</a> f s</p></div><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant-Utils-Links.html#t:Link" target="main">Link</a></p></div><div class="top"><p class="src"><span class="keyword">class</span> <a href="Servant-Utils-Links.html#t:VLinkHelper" target="main">VLinkHelper</a> f</p></div></div></body></html>
mini_Servant-Utils-StaticFiles.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant.Utils.StaticFiles</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant.Utils.StaticFiles</p></div><div id="interface"><div class="top"><p class="src"><a href="Servant-Utils-StaticFiles.html#v:serveDirectory" target="main">serveDirectory</a></p></div></div></body></html>
mini_Servant.htmlnew file+4
@@ -0,0 +1,4 @@
1+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Servant</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
2+window.onload = function () {pageLoad();};
3+//]]>
4+</script></head><body id="mini"><div id="module-header"><p class="caption">Servant</p></div><div id="interface"><div class="top"><p class="src"><span class="keyword">data</span> <a href="Servant.html#t:Proxy" target="main">Proxy</a> t</p></div></div></body></html>
minus.gifnew file

Binary file not shown.

ocean.cssnew file+577
@@ -0,0 +1,577 @@
1+/* @group Fundamentals */
2+
3+* { margin: 0; padding: 0 }
4+
5+/* Is this portable? */
6+html {
7+ background-color: white;
8+ width: 100%;
9+ height: 100%;
10+}
11+
12+body {
13+ background: white;
14+ color: black;
15+ text-align: left;
16+ min-height: 100%;
17+ position: relative;
18+}
19+
20+p {
21+ margin: 0.8em 0;
22+}
23+
24+ul, ol {
25+ margin: 0.8em 0 0.8em 2em;
26+}
27+
28+dl {
29+ margin: 0.8em 0;
30+}
31+
32+dt {
33+ font-weight: bold;
34+}
35+dd {
36+ margin-left: 2em;
37+}
38+
39+a { text-decoration: none; }
40+a[href]:link { color: rgb(196,69,29); }
41+a[href]:visited { color: rgb(171,105,84); }
42+a[href]:hover { text-decoration:underline; }
43+
44+/* @end */
45+
46+/* @group Fonts & Sizes */
47+
48+/* Basic technique & IE workarounds from YUI 3
49+ For reasons, see:
50+ http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css
51+ */
52+
53+body {
54+ font:13px/1.4 sans-serif;
55+ *font-size:small; /* for IE */
56+ *font:x-small; /* for IE in quirks mode */
57+}
58+
59+h1 { font-size: 146.5%; /* 19pt */ }
60+h2 { font-size: 131%; /* 17pt */ }
61+h3 { font-size: 116%; /* 15pt */ }
62+h4 { font-size: 100%; /* 13pt */ }
63+h5 { font-size: 100%; /* 13pt */ }
64+
65+select, input, button, textarea {
66+ font:99% sans-serif;
67+}
68+
69+table {
70+ font-size:inherit;
71+ font:100%;
72+}
73+
74+pre, code, kbd, samp, tt, .src {
75+ font-family:monospace;
76+ *font-size:108%;
77+ line-height: 124%;
78+}
79+
80+.links, .link {
81+ font-size: 85%; /* 11pt */
82+}
83+
84+#module-header .caption {
85+ font-size: 182%; /* 24pt */
86+}
87+
88+.info {
89+ font-size: 85%; /* 11pt */
90+}
91+
92+#table-of-contents, #synopsis {
93+ /* font-size: 85%; /* 11pt */
94+}
95+
96+
97+/* @end */
98+
99+/* @group Common */
100+
101+.caption, h1, h2, h3, h4, h5, h6 {
102+ font-weight: bold;
103+ color: rgb(78,98,114);
104+ margin: 0.8em 0 0.4em;
105+}
106+
107+* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 {
108+ margin-top: 2em;
109+}
110+
111+h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 {
112+ margin-top: inherit;
113+}
114+
115+ul.links {
116+ list-style: none;
117+ text-align: left;
118+ float: right;
119+ display: inline-table;
120+ margin: 0 0 0 1em;
121+}
122+
123+ul.links li {
124+ display: inline;
125+ border-left: 1px solid #d5d5d5;
126+ white-space: nowrap;
127+ padding: 0;
128+}
129+
130+ul.links li a {
131+ padding: 0.2em 0.5em;
132+}
133+
134+.hide { display: none; }
135+.show { display: inherit; }
136+.clear { clear: both; }
137+
138+.collapser {
139+ background-image: url(minus.gif);
140+ background-repeat: no-repeat;
141+}
142+.expander {
143+ background-image: url(plus.gif);
144+ background-repeat: no-repeat;
145+}
146+p.caption.collapser,
147+p.caption.expander {
148+ background-position: 0 0.4em;
149+}
150+.collapser, .expander {
151+ padding-left: 14px;
152+ margin-left: -14px;
153+ cursor: pointer;
154+}
155+
156+pre {
157+ padding: 0.25em;
158+ margin: 0.8em 0;
159+ background: rgb(229,237,244);
160+ overflow: auto;
161+ border-bottom: 0.25em solid white;
162+ /* white border adds some space below the box to compensate
163+ for visual extra space that paragraphs have between baseline
164+ and the bounding box */
165+}
166+
167+.src {
168+ background: #f0f0f0;
169+ padding: 0.2em 0.5em;
170+}
171+
172+.keyword { font-weight: normal; }
173+.def { font-weight: bold; }
174+
175+
176+/* @end */
177+
178+/* @group Page Structure */
179+
180+#content {
181+ margin: 0 auto;
182+ padding: 0 2em 6em;
183+}
184+
185+#package-header {
186+ background: rgb(41,56,69);
187+ border-top: 5px solid rgb(78,98,114);
188+ color: #ddd;
189+ padding: 0.2em;
190+ position: relative;
191+ text-align: left;
192+}
193+
194+#package-header .caption {
195+ background: url(hslogo-16.png) no-repeat 0em;
196+ color: white;
197+ margin: 0 2em;
198+ font-weight: normal;
199+ font-style: normal;
200+ padding-left: 2em;
201+}
202+
203+#package-header a:link, #package-header a:visited { color: white; }
204+#package-header a:hover { background: rgb(78,98,114); }
205+
206+#module-header .caption {
207+ color: rgb(78,98,114);
208+ font-weight: bold;
209+ border-bottom: 1px solid #ddd;
210+}
211+
212+table.info {
213+ float: right;
214+ padding: 0.5em 1em;
215+ border: 1px solid #ddd;
216+ color: rgb(78,98,114);
217+ background-color: #fff;
218+ max-width: 40%;
219+ border-spacing: 0;
220+ position: relative;
221+ top: -0.5em;
222+ margin: 0 0 0 2em;
223+}
224+
225+.info th {
226+ padding: 0 1em 0 0;
227+}
228+
229+div#style-menu-holder {
230+ position: relative;
231+ z-index: 2;
232+ display: inline;
233+}
234+
235+#style-menu {
236+ position: absolute;
237+ z-index: 1;
238+ overflow: visible;
239+ background: #374c5e;
240+ margin: 0;
241+ text-align: center;
242+ right: 0;
243+ padding: 0;
244+ top: 1.25em;
245+}
246+
247+#style-menu li {
248+ display: list-item;
249+ border-style: none;
250+ margin: 0;
251+ padding: 0;
252+ color: #000;
253+ list-style-type: none;
254+}
255+
256+#style-menu li + li {
257+ border-top: 1px solid #919191;
258+}
259+
260+#style-menu a {
261+ width: 6em;
262+ padding: 3px;
263+ display: block;
264+}
265+
266+#footer {
267+ background: #ddd;
268+ border-top: 1px solid #aaa;
269+ padding: 0.5em 0;
270+ color: #666;
271+ text-align: center;
272+ position: absolute;
273+ bottom: 0;
274+ width: 100%;
275+ height: 3em;
276+}
277+
278+/* @end */
279+
280+/* @group Front Matter */
281+
282+#table-of-contents {
283+ float: right;
284+ clear: right;
285+ background: #faf9dc;
286+ border: 1px solid #d8d7ad;
287+ padding: 0.5em 1em;
288+ max-width: 20em;
289+ margin: 0.5em 0 1em 1em;
290+}
291+
292+#table-of-contents .caption {
293+ text-align: center;
294+ margin: 0;
295+}
296+
297+#table-of-contents ul {
298+ list-style: none;
299+ margin: 0;
300+}
301+
302+#table-of-contents ul ul {
303+ margin-left: 2em;
304+}
305+
306+#description .caption {
307+ display: none;
308+}
309+
310+#synopsis {
311+ display: none;
312+}
313+
314+.no-frame #synopsis {
315+ display: block;
316+ position: fixed;
317+ right: 0;
318+ height: 80%;
319+ top: 10%;
320+ padding: 0;
321+}
322+
323+#synopsis .caption {
324+ float: left;
325+ width: 29px;
326+ color: rgba(255,255,255,0);
327+ height: 110px;
328+ margin: 0;
329+ font-size: 1px;
330+ padding: 0;
331+}
332+
333+#synopsis p.caption.collapser {
334+ background: url(synopsis.png) no-repeat -64px -8px;
335+}
336+
337+#synopsis p.caption.expander {
338+ background: url(synopsis.png) no-repeat 0px -8px;
339+}
340+
341+#synopsis ul {
342+ height: 100%;
343+ overflow: auto;
344+ padding: 0.5em;
345+ margin: 0;
346+}
347+
348+#synopsis ul ul {
349+ overflow: hidden;
350+}
351+
352+#synopsis ul,
353+#synopsis ul li.src {
354+ background-color: #faf9dc;
355+ white-space: nowrap;
356+ list-style: none;
357+ margin-left: 0;
358+}
359+
360+/* @end */
361+
362+/* @group Main Content */
363+
364+#interface div.top { margin: 2em 0; }
365+#interface h1 + div.top,
366+#interface h2 + div.top,
367+#interface h3 + div.top,
368+#interface h4 + div.top,
369+#interface h5 + div.top {
370+ margin-top: 1em;
371+}
372+#interface p.src .link {
373+ float: right;
374+ color: #919191;
375+ border-left: 1px solid #919191;
376+ background: #f0f0f0;
377+ padding: 0 0.5em 0.2em;
378+ margin: 0 -0.5em 0 0.5em;
379+}
380+
381+#interface span.fixity {
382+ color: #919191;
383+ border-left: 1px solid #919191;
384+ padding: 0.2em 0.5em 0.2em 0.5em;
385+ margin: 0 -1em 0 1em;
386+}
387+
388+#interface span.rightedge {
389+ border-left: 1px solid #919191;
390+ padding: 0.2em 0 0.2em 0;
391+ margin: 0 0 0 1em;
392+}
393+
394+#interface table { border-spacing: 2px; }
395+#interface td {
396+ vertical-align: top;
397+ padding-left: 0.5em;
398+}
399+#interface td.src {
400+ white-space: nowrap;
401+}
402+#interface td.doc p {
403+ margin: 0;
404+}
405+#interface td.doc p + p {
406+ margin-top: 0.8em;
407+}
408+
409+.subs dl {
410+ margin: 0;
411+}
412+
413+.subs dt {
414+ float: left;
415+ clear: left;
416+ display: block;
417+ margin: 1px 0;
418+}
419+
420+.subs dd {
421+ float: right;
422+ width: 90%;
423+ display: block;
424+ padding-left: 0.5em;
425+ margin-bottom: 0.5em;
426+}
427+
428+.subs dd.empty {
429+ display: none;
430+}
431+
432+.subs dd p {
433+ margin: 0;
434+}
435+
436+/* Render short-style data instances */
437+.inst ul {
438+ height: 100%;
439+ padding: 0.5em;
440+ margin: 0;
441+}
442+
443+.inst, .inst li {
444+ list-style: none;
445+ margin-left: 1em;
446+}
447+
448+.top p.src {
449+ border-top: 1px solid #ccc;
450+}
451+
452+.subs, .doc {
453+ /* use this selector for one level of indent */
454+ padding-left: 2em;
455+}
456+
457+.warning {
458+ color: red;
459+}
460+
461+.arguments {
462+ margin-top: -0.4em;
463+}
464+.arguments .caption {
465+ display: none;
466+}
467+
468+.fields { padding-left: 1em; }
469+
470+.fields .caption { display: none; }
471+
472+.fields p { margin: 0 0; }
473+
474+/* this seems bulky to me
475+.methods, .constructors {
476+ background: #f8f8f8;
477+ border: 1px solid #eee;
478+}
479+*/
480+
481+/* @end */
482+
483+/* @group Auxillary Pages */
484+
485+
486+.extension-list {
487+ list-style-type: none;
488+ margin-left: 0;
489+}
490+
491+#mini {
492+ margin: 0 auto;
493+ padding: 0 1em 1em;
494+}
495+
496+#mini > * {
497+ font-size: 93%; /* 12pt */
498+}
499+
500+#mini #module-list .caption,
501+#mini #module-header .caption {
502+ font-size: 125%; /* 15pt */
503+}
504+
505+#mini #interface h1,
506+#mini #interface h2,
507+#mini #interface h3,
508+#mini #interface h4 {
509+ font-size: 109%; /* 13pt */
510+ margin: 1em 0 0;
511+}
512+
513+#mini #interface .top,
514+#mini #interface .src {
515+ margin: 0;
516+}
517+
518+#mini #module-list ul {
519+ list-style: none;
520+ margin: 0;
521+}
522+
523+#alphabet ul {
524+ list-style: none;
525+ padding: 0;
526+ margin: 0.5em 0 0;
527+ text-align: center;
528+}
529+
530+#alphabet li {
531+ display: inline;
532+ margin: 0 0.25em;
533+}
534+
535+#alphabet a {
536+ font-weight: bold;
537+}
538+
539+#index .caption,
540+#module-list .caption { font-size: 131%; /* 17pt */ }
541+
542+#index table {
543+ margin-left: 2em;
544+}
545+
546+#index .src {
547+ font-weight: bold;
548+}
549+#index .alt {
550+ font-size: 77%; /* 10pt */
551+ font-style: italic;
552+ padding-left: 2em;
553+}
554+
555+#index td + td {
556+ padding-left: 1em;
557+}
558+
559+#module-list ul {
560+ list-style: none;
561+ margin: 0 0 0 2em;
562+}
563+
564+#module-list li {
565+ clear: right;
566+}
567+
568+#module-list span.collapser,
569+#module-list span.expander {
570+ background-position: 0 0.3em;
571+}
572+
573+#module-list .package {
574+ float: right;
575+}
576+
577+/* @end */
plus.gifnew file

Binary file not shown.

servant.haddocknew file

Binary file not shown.

servant.txtnew file+611
@@ -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" :&gt; Get [Book] -- GET /books
62+-- :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books
63+--
64+-- server :: Server MyApi
65+-- server = listAllBooks :&lt;|&gt; 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+-- &gt; mempty = NotFound
90+-- &gt;
91+-- &gt; NotFound <a>mappend</a> x = x
92+-- &gt; WrongMethod <a>mappend</a> InvalidBody = InvalidBody
93+-- &gt; WrongMethod <a>mappend</a> _ = WrongMethod
94+-- &gt; 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" :&gt; "world" :&gt; 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" :&gt; Get [Book] -- GET /books
146+-- :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books
147+-- </pre>
148+data (:<|>) a b
149+(:<|>) :: a -> b -> (:<|>) a b
150+
151+-- | A server for <tt>a <a>:&lt;|&gt;</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" :&gt; Get [Book] -- GET /books
157+-- :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books
158+--
159+-- server :: Server MyApi
160+-- server = listAllBooks :&lt;|&gt; 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" :&gt; Capture "isbn" Text :&gt; 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=&lt;author name&gt;
188+-- type MyApi = "books" :&gt; QueryParam "author" Text :&gt; 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" :&gt; QueryParam "author" Text :&gt; Get [Book]
209+--
210+-- server :: Server MyApi
211+-- server = getBooksBy
212+-- where getBooksBy :: Maybe Text -&gt; 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&amp;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&amp;param=val2</tt>, too.
223+--
224+-- Example:
225+--
226+-- <pre>
227+-- -- /books?authors[]=&lt;author1&gt;&amp;authors[]=&lt;author2&gt;&amp;...
228+-- type MyApi = "books" :&gt; QueryParams "authors" Text :&gt; 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" :&gt; QueryParams "authors" Text :&gt; Get [Book]
249+--
250+-- server :: Server MyApi
251+-- server = getBooksBy
252+-- where getBooksBy :: [Text] -&gt; 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" :&gt; QueryFlag "published" :&gt; 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" :&gt; QueryFlag "published" :&gt; Get [Book]
277+--
278+-- server :: Server MyApi
279+-- server = getBooks
280+-- where getBooks :: Bool -&gt; 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" :&gt; ReqBody Book :&gt; 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" :&gt; ReqBody Book :&gt; Post Book
311+--
312+-- server :: Server MyApi
313+-- server = postBook
314+-- where postBook :: Book -&gt; 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" :&gt; 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" :&gt; ReqBody Book :&gt; 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" :&gt; Capture "isbn" Text :&gt; 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" :&gt; Capture "isbn" Text :&gt; ReqBody Book :&gt; 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 -&gt; ()
429+-- POST hello/p:Int String -&gt; ()
430+-- GET hello/?name:String Int
431+-- |]
432+-- </pre>
433+--
434+-- Will generate:
435+--
436+-- <pre>
437+-- "hello" :&gt; ReqBody String :&gt; Put ()
438+-- :&lt;|&gt; "hello" :&gt; Capture "p" Int :&gt; ReqBody String :&gt; Post ()
439+-- :&lt;|&gt; "hello" :&gt; QueryParam "name" String :&gt; 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> -&gt; <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" :&gt; Get Int
505+-- :<a>|</a> "bye" :&gt; QueryParam "name" String :&gt; Post Bool)
506+--
507+-- api :: API
508+-- api = proxy
509+--
510+-- link1 :: Proxy ("hello" :&gt; Get Int)
511+-- link1 = proxy
512+--
513+-- link2 :: Proxy ("hello" :&gt; 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>:&gt;</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" :&gt; 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" :&gt; Raw
585+--
586+-- server :: Server MyApi
587+-- server = serveDirectory "/var/www"
588+-- </pre>
589+--
590+-- would capture any request to <tt>/static/&lt;something&gt;</tt> and
591+-- look for <tt>&lt;something&gt;</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
src/Servant-API-Alternative.htmlnew file+50
@@ -0,0 +1,50 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Alternative.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
13+<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span> <span class='hs-keyword'>where</span>
14+<a name="line-5"></a>
15+<a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Monoid</span>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
18+<a name="line-9"></a>
19+<a name="line-10"></a><span class='hs-comment'>-- | Union of two APIs, first takes precedence in case of overlap.</span>
20+<a name="line-11"></a><span class='hs-comment'>--</span>
21+<a name="line-12"></a><span class='hs-comment'>-- Example:</span>
22+<a name="line-13"></a><span class='hs-comment'>--</span>
23+<a name="line-14"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Get [Book] -- GET /books</span>
24+<a name="line-15"></a><span class='hs-comment'>-- &gt; :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books</span>
25+<a name="line-16"></a><span class='hs-keyword'>data</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>b</span>
26+<a name="line-17"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>8</span> <span class='hs-conop'>:&lt;|&gt;</span>
27+<a name="line-18"></a>
28+<a name="line-19"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- | A server for @a ':&lt;|&gt;' b@ first tries to match the request again the route</span>
29+<a name="line-20"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- represented by @a@ and if it fails tries @b@. You must provide a request</span>
30+<a name="line-21"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- handler for each route.</span>
31+<a name="line-22"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>--</span>
32+<a name="line-23"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Get [Book] -- GET /books</span>
33+<a name="line-24"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt;</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
36+<a name="line-27"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; server = listAllBooks :&lt;|&gt; postBook</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; where listAllBooks = ...</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-comment'>-- &gt; postBook book = ...</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(a%20:%3c%7c%3e%20b)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>HasServer</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
40+<a name="line-31"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>b</span>
41+<a name="line-32"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span>
42+<a name="line-33"></a> <span class='hs-varid'>route</span> <span class='hs-varid'>pa</span> <span class='hs-varid'>a</span> <span class='hs-varid'>request</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span> <span class='hs-varid'>mResponse</span> <span class='hs-keyglyph'>-&gt;</span>
43+<a name="line-34"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>isMismatch</span> <span class='hs-varid'>mResponse</span>
44+<a name="line-35"></a> <span class='hs-keyword'>then</span> <span class='hs-varid'>route</span> <span class='hs-varid'>pb</span> <span class='hs-varid'>b</span> <span class='hs-varid'>request</span> <span class='hs-varop'>$</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>mResponse'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>respond</span> <span class='hs-layout'>(</span><span class='hs-varid'>mResponse</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>mResponse'</span><span class='hs-layout'>)</span>
45+<a name="line-36"></a> <span class='hs-keyword'>else</span> <span class='hs-varid'>respond</span> <span class='hs-varid'>mResponse</span>
46+<a name="line-37"></a>
47+<a name="line-38"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>pa</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>a</span>
48+<a name="line-39"></a> <span class='hs-varid'>pb</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>b</span>
49+</pre></body>
50+</html>
src/Servant-API-Capture.htmlnew file+71
@@ -0,0 +1,71 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Capture.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleContexts #-}</span>
14+<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
15+<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
16+<a name="line-7"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
17+<a name="line-8"></a>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
23+<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
24+<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
25+<a name="line-16"></a>
26+<a name="line-17"></a><span class='hs-comment'>-- | Capture a value from the request path under a certain type @a@.</span>
27+<a name="line-18"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><span class='hs-comment'>-- Example:</span>
29+<a name="line-20"></a><span class='hs-comment'>--</span>
30+<a name="line-21"></a><span class='hs-comment'>-- &gt; -- GET /books/:isbn</span>
31+<a name="line-22"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Capture "isbn" Text :&gt; Get Book</span>
32+<a name="line-23"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Capture</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
33+<a name="line-24"></a>
34+<a name="line-25"></a><a name="captured"></a><span class='hs-definition'>captured</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-varid'>proxy</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
35+<a name="line-26"></a><span class='hs-definition'>captured</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromText</span>
36+<a name="line-27"></a>
37+<a name="line-28"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use 'Capture' in one of the endpoints for your API,</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of the type specified by the 'Capture'.</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about getting it from the URL and turning</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- it into a value of the type you specify.</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how it'll be converted from 'Text' to your type</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
45+<a name="line-36"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
46+<a name="line-37"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
47+<a name="line-38"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
48+<a name="line-39"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Capture "isbn" Text :&gt; Get Book</span>
49+<a name="line-40"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt;</span>
50+<a name="line-41"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
51+<a name="line-42"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server = getBook</span>
52+<a name="line-43"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; where getBook :: Text -&gt; EitherT (Int, String) IO Book</span>
53+<a name="line-44"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; getBook isbn = ...</span>
54+<a name="line-45"></a><a name="instance%20HasServer%20(Capture%20capture%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>capture</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
55+<a name="line-46"></a> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
56+<a name="line-47"></a>
57+<a name="line-48"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
58+<a name="line-49"></a> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
59+<a name="line-50"></a>
60+<a name="line-51"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span> <span class='hs-keyword'>of</span>
61+<a name="line-52"></a> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span>
62+<a name="line-53"></a> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>captured</span> <span class='hs-varid'>captureProxy</span> <span class='hs-varid'>first</span> <span class='hs-keyword'>of</span>
63+<a name="line-54"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
64+<a name="line-55"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span><span class='hs-layout'>{</span>
65+<a name="line-56"></a> <span class='hs-varid'>pathInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rest</span>
66+<a name="line-57"></a> <span class='hs-layout'>}</span> <span class='hs-varid'>respond</span>
67+<a name="line-58"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
68+<a name="line-59"></a>
69+<a name="line-60"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>captureProxy</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
70+</pre></body>
71+</html>
src/Servant-API-Delete.htmlnew file+59
@@ -0,0 +1,59 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Delete.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span> <span class='hs-keyword'>where</span>
15+<a name="line-6"></a>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
23+<a name="line-14"></a>
24+<a name="line-15"></a><a name="Delete"></a><span class='hs-comment'>-- | Combinator for DELETE requests.</span>
25+<a name="line-16"></a><a name="Delete"></a><span class='hs-comment'>--</span>
26+<a name="line-17"></a><a name="Delete"></a><span class='hs-comment'>-- Example:</span>
27+<a name="line-18"></a><a name="Delete"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><a name="Delete"></a><span class='hs-comment'>-- &gt; -- DELETE /books/:isbn</span>
29+<a name="line-20"></a><a name="Delete"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Capture "isbn" Text :&gt; Delete</span>
30+<a name="line-21"></a><a name="Delete"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Delete</span>
31+<a name="line-22"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
32+<a name="line-23"></a>
33+<a name="line-24"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- | If you have a 'Delete' endpoint in your API,</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- the handler for this endpoint is meant to delete</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- a resource.</span>
36+<a name="line-27"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>--</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- The code of the handler will, just like</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- for 'Servant.API.Get.Get', 'Servant.API.Post.Post' and</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- 'Servant.API.Put.Put', run in @EitherT (Int, String) IO ()@.</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- The 'Int' represents the status code and the 'String' a message</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- to be returned. You can use 'Control.Monad.Trans.Either.left' to</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- painlessly error out if the conditions for a successful deletion</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-comment'>-- are not met.</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20Delete"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>HasServer</span> <span class='hs-conid'>Delete</span> <span class='hs-keyword'>where</span>
45+<a name="line-36"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Delete</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
46+<a name="line-37"></a>
47+<a name="line-38"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
48+<a name="line-39"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodDelete</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
49+<a name="line-40"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
50+<a name="line-41"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
51+<a name="line-42"></a> <span class='hs-conid'>Right</span> <span class='hs-conid'>()</span> <span class='hs-keyglyph'>-&gt;</span>
52+<a name="line-43"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>status204</span> <span class='hs-conid'>[]</span> <span class='hs-str'>""</span>
53+<a name="line-44"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
54+<a name="line-45"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
55+<a name="line-46"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodDelete</span> <span class='hs-keyglyph'>=</span>
56+<a name="line-47"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
57+<a name="line-48"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
58+</pre></body>
59+</html>
src/Servant-API-Get.htmlnew file+58
@@ -0,0 +1,58 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Get.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span> <span class='hs-keyword'>where</span>
15+<a name="line-6"></a>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
23+<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
24+<a name="line-15"></a>
25+<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for simple GET requests. Serves the result as JSON.</span>
26+<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
27+<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
28+<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
29+<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Get [Book]</span>
30+<a name="line-21"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Get</span> <span class='hs-varid'>a</span>
31+<a name="line-22"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
32+<a name="line-23"></a>
33+<a name="line-24"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Get' endpoint,</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Post.Post'</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- and 'Servant.API.Put.Put', the handler code runs in the</span>
36+<a name="line-27"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>--</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-comment'>-- yielding status code 200 along the way.</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(Get%20result)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>result</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>result</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
45+<a name="line-36"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>result</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>result</span>
46+<a name="line-37"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
47+<a name="line-38"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodGet</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
48+<a name="line-39"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
49+<a name="line-40"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
50+<a name="line-41"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>output</span> <span class='hs-keyglyph'>-&gt;</span>
51+<a name="line-42"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>ok200</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>output</span><span class='hs-layout'>)</span>
52+<a name="line-43"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
53+<a name="line-44"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
54+<a name="line-45"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodGet</span> <span class='hs-keyglyph'>=</span>
55+<a name="line-46"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
56+<a name="line-47"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
57+</pre></body>
58+</html>
src/Servant-API-Post.htmlnew file+64
@@ -0,0 +1,64 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Post.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span> <span class='hs-keyword'>where</span>
15+<a name="line-6"></a>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
23+<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
24+<a name="line-15"></a>
25+<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for POST requests. The type variable represents the type of the</span>
26+<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- response body (not the request body, use 'Servant.API.RQBody.RQBody' for</span>
27+<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>-- that).</span>
28+<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
29+<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
30+<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
31+<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- POST /books</span>
32+<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- with a JSON encoded Book as the request body</span>
33+<a name="line-24"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- returning the just-created Book</span>
34+<a name="line-25"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; ReqBody Book :&gt; Post Book</span>
35+<a name="line-26"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Post</span> <span class='hs-varid'>a</span>
36+<a name="line-27"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
37+<a name="line-28"></a>
38+<a name="line-29"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Post' endpoint,</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- and 'Servant.API.Put.Put', the handler code runs in the</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
45+<a name="line-36"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>--</span>
46+<a name="line-37"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
47+<a name="line-38"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
48+<a name="line-39"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-comment'>-- yielding status code 201 along the way.</span>
49+<a name="line-40"></a><a name="instance%20HasServer%20(Post%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
50+<a name="line-41"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span>
51+<a name="line-42"></a>
52+<a name="line-43"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
53+<a name="line-44"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodPost</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
54+<a name="line-45"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
55+<a name="line-46"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
56+<a name="line-47"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>out</span> <span class='hs-keyglyph'>-&gt;</span>
57+<a name="line-48"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>status201</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>out</span><span class='hs-layout'>)</span>
58+<a name="line-49"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
59+<a name="line-50"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
60+<a name="line-51"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodPost</span> <span class='hs-keyglyph'>=</span>
61+<a name="line-52"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
62+<a name="line-53"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
63+</pre></body>
64+</html>
src/Servant-API-Put.htmlnew file+63
@@ -0,0 +1,63 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Put.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE DeriveDataTypeable #-}</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span> <span class='hs-keyword'>where</span>
15+<a name="line-6"></a>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span><span class='hs-varop'>.</span><span class='hs-conid'>Trans</span><span class='hs-varop'>.</span><span class='hs-conid'>Either</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Typeable</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
23+<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
24+<a name="line-15"></a>
25+<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>-- | Endpoint for PUT requests, usually used to update a ressource.</span>
26+<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- The type @a@ is the type of the response body that's returned.</span>
27+<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
29+<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
30+<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- PUT /books/:isbn</span>
31+<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- with a Book as request body, returning the updated Book</span>
32+<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Capture "isbn" Text :&gt; ReqBody Book :&gt; Put Book</span>
33+<a name="line-24"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Put</span> <span class='hs-varid'>a</span>
34+<a name="line-25"></a> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Typeable</span>
35+<a name="line-26"></a>
36+<a name="line-27"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- | When implementing the handler for a 'Put' endpoint,</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- just like for 'Servant.API.Delete.Delete', 'Servant.API.Get.Get'</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- and 'Servant.API.Post.Post', the handler code runs in the</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- @EitherT (Int, String) IO@ monad, where the 'Int' represents</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- the status code and the 'String' a message, returned in case of</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- failure. You can quite handily use 'Control.Monad.Trans.EitherT.left'</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- to quickly fail if some conditions are not met.</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>--</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- If successfully returning a value, we just require that its type has</span>
45+<a name="line-36"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- a 'ToJSON' instance and servant takes care of encoding it for you,</span>
46+<a name="line-37"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-comment'>-- yielding status code 200 along the way.</span>
47+<a name="line-38"></a><a name="instance%20HasServer%20(Put%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToJSON</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>Put</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
48+<a name="line-39"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>Put</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EitherT</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span>
49+<a name="line-40"></a>
50+<a name="line-41"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>action</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
51+<a name="line-42"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>==</span> <span class='hs-varid'>methodPut</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
52+<a name="line-43"></a> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>runEitherT</span> <span class='hs-varid'>action</span>
53+<a name="line-44"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>of</span>
54+<a name="line-45"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>out</span> <span class='hs-keyglyph'>-&gt;</span>
55+<a name="line-46"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>ok200</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-str'>"Content-Type"</span><span class='hs-layout'>,</span> <span class='hs-str'>"application/json"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-layout'>(</span><span class='hs-varid'>encode</span> <span class='hs-varid'>out</span><span class='hs-layout'>)</span>
56+<a name="line-47"></a> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>status</span><span class='hs-layout'>,</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
57+<a name="line-48"></a> <span class='hs-varid'>responseLBS</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStatus</span> <span class='hs-varid'>status</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>[]</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span> <span class='hs-varid'>message</span><span class='hs-layout'>)</span>
58+<a name="line-49"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>null</span> <span class='hs-layout'>(</span><span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>requestMethod</span> <span class='hs-varid'>request</span> <span class='hs-varop'>/=</span> <span class='hs-varid'>methodPut</span> <span class='hs-keyglyph'>=</span>
59+<a name="line-50"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>WrongMethod</span>
60+<a name="line-51"></a>
61+<a name="line-52"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
62+</pre></body>
63+</html>
src/Servant-API-QueryParam.htmlnew file+173
@@ -0,0 +1,173 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/QueryParam.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleContexts #-}</span>
14+<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
15+<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
16+<a name="line-7"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
17+<a name="line-8"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span> <span class='hs-keyword'>where</span>
18+<a name="line-9"></a>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Maybe</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
23+<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
24+<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
25+<a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
26+<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
27+<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
28+<a name="line-19"></a>
29+<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup the value associated to the @sym@ query string parameter</span>
30+<a name="line-21"></a><a name="HasServer"></a><span class='hs-comment'>-- and try to extract it as a value of type @a@.</span>
31+<a name="line-22"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
32+<a name="line-23"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
33+<a name="line-24"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
34+<a name="line-25"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- /books?author=&lt;author name&gt;</span>
35+<a name="line-26"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryParam "author" Text :&gt; Get [Book]</span>
36+<a name="line-27"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
37+<a name="line-28"></a>
38+<a name="line-29"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryParam' "author" Text@ in one of the endpoints for your API,</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type @'Maybe' 'Text'@.</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about looking it up in the query string</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- and turning it into a value of the type you specify, enclosed</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- in 'Maybe', because it may not be there and servant would then</span>
45+<a name="line-36"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- hand you 'Nothing'.</span>
46+<a name="line-37"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
47+<a name="line-38"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how it'll be converted from 'Text' to your type</span>
48+<a name="line-39"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
49+<a name="line-40"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
50+<a name="line-41"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
51+<a name="line-42"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
52+<a name="line-43"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryParam "author" Text :&gt; Get [Book]</span>
53+<a name="line-44"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt;</span>
54+<a name="line-45"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
55+<a name="line-46"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server = getBooksBy</span>
56+<a name="line-47"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; where getBooksBy :: Maybe Text -&gt; EitherT (Int, String) IO [Book]</span>
57+<a name="line-48"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; getBooksBy Nothing = ...return all books...</span>
58+<a name="line-49"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; getBooksBy (Just author) = ...return books by the given author...</span>
59+<a name="line-50"></a><a name="instance%20HasServer%20(QueryParam%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
60+<a name="line-51"></a> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
61+<a name="line-52"></a>
62+<a name="line-53"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
63+<a name="line-54"></a> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
64+<a name="line-55"></a>
65+<a name="line-56"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
66+<a name="line-57"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
67+<a name="line-58"></a> <span class='hs-varid'>param</span> <span class='hs-keyglyph'>=</span>
68+<a name="line-59"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>paramname</span> <span class='hs-varid'>querytext</span> <span class='hs-keyword'>of</span>
69+<a name="line-60"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nothing</span> <span class='hs-comment'>-- param absent from the query string</span>
70+<a name="line-61"></a> <span class='hs-conid'>Just</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Nothing</span> <span class='hs-comment'>-- param present with no value -&gt; Nothing</span>
71+<a name="line-62"></a> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fromText</span> <span class='hs-varid'>v</span> <span class='hs-comment'>-- if present, we try to convert to</span>
72+<a name="line-63"></a> <span class='hs-comment'>-- the right type</span>
73+<a name="line-64"></a>
74+<a name="line-65"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>param</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
75+<a name="line-66"></a>
76+<a name="line-67"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
77+<a name="line-68"></a>
78+<a name="line-69"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup the values associated to the @sym@ query string parameter</span>
79+<a name="line-70"></a><a name="HasServer"></a><span class='hs-comment'>-- and try to extract it as a value of type @[a]@. This is typically</span>
80+<a name="line-71"></a><a name="HasServer"></a><span class='hs-comment'>-- meant to support query string parameters of the form</span>
81+<a name="line-72"></a><a name="HasServer"></a><span class='hs-comment'>-- @param[]=val1&amp;param[]=val2@ and so on. Note that servant doesn't actually</span>
82+<a name="line-73"></a><a name="HasServer"></a><span class='hs-comment'>-- require the @[]@s and will fetch the values just fine with</span>
83+<a name="line-74"></a><a name="HasServer"></a><span class='hs-comment'>-- @param=val1&amp;param=val2@, too.</span>
84+<a name="line-75"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
85+<a name="line-76"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
86+<a name="line-77"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
87+<a name="line-78"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- /books?authors[]=&lt;author1&gt;&amp;authors[]=&lt;author2&gt;&amp;...</span>
88+<a name="line-79"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryParams "authors" Text :&gt; Get [Book]</span>
89+<a name="line-80"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span>
90+<a name="line-81"></a>
91+<a name="line-82"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryParams' "authors" Text@ in one of the endpoints for your API,</span>
92+<a name="line-83"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
93+<a name="line-84"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type @['Text']@.</span>
94+<a name="line-85"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
95+<a name="line-86"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about looking up 0 or more values in the query string</span>
96+<a name="line-87"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- associated to @authors@ and turning each of them into a value of</span>
97+<a name="line-88"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- the type you specify.</span>
98+<a name="line-89"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
99+<a name="line-90"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- You can control how the individual values are converted from 'Text' to your type</span>
100+<a name="line-91"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- by simply providing an instance of 'FromText' for your type.</span>
101+<a name="line-92"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
102+<a name="line-93"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
103+<a name="line-94"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
104+<a name="line-95"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryParams "authors" Text :&gt; Get [Book]</span>
105+<a name="line-96"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt;</span>
106+<a name="line-97"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
107+<a name="line-98"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server = getBooksBy</span>
108+<a name="line-99"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; where getBooksBy :: [Text] -&gt; EitherT (Int, String) IO [Book]</span>
109+<a name="line-100"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; getBooksBy authors = ...return all books by these authors...</span>
110+<a name="line-101"></a><a name="instance%20HasServer%20(QueryParams%20sym%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
111+<a name="line-102"></a> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
112+<a name="line-103"></a>
113+<a name="line-104"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParams</span> <span class='hs-varid'>sym</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
114+<a name="line-105"></a> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
115+<a name="line-106"></a>
116+<a name="line-107"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
117+<a name="line-108"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
118+<a name="line-109"></a> <span class='hs-comment'>-- if sym is "foo", we look for query string parameters</span>
119+<a name="line-110"></a> <span class='hs-comment'>-- named "foo" or "foo[]" and call fromText on the</span>
120+<a name="line-111"></a> <span class='hs-comment'>-- corresponding values</span>
121+<a name="line-112"></a> <span class='hs-varid'>parameters</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>filter</span> <span class='hs-varid'>looksLikeParam</span> <span class='hs-varid'>querytext</span>
122+<a name="line-113"></a> <span class='hs-varid'>values</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>catMaybes</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>convert</span> <span class='hs-varop'>.</span> <span class='hs-varid'>snd</span><span class='hs-layout'>)</span> <span class='hs-varid'>parameters</span>
123+<a name="line-114"></a>
124+<a name="line-115"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>values</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
125+<a name="line-116"></a>
126+<a name="line-117"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
127+<a name="line-118"></a> <span class='hs-varid'>looksLikeParam</span> <span class='hs-layout'>(</span><span class='hs-varid'>name</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>name</span> <span class='hs-varop'>==</span> <span class='hs-varid'>paramname</span> <span class='hs-varop'>||</span> <span class='hs-varid'>name</span> <span class='hs-varop'>==</span> <span class='hs-layout'>(</span><span class='hs-varid'>paramname</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-str'>"[]"</span><span class='hs-layout'>)</span>
128+<a name="line-119"></a> <span class='hs-varid'>convert</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
129+<a name="line-120"></a> <span class='hs-varid'>convert</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromText</span> <span class='hs-varid'>v</span>
130+<a name="line-121"></a>
131+<a name="line-122"></a><a name="HasServer"></a><span class='hs-comment'>-- | Lookup a potentially value-less query string parameter</span>
132+<a name="line-123"></a><a name="HasServer"></a><span class='hs-comment'>-- with boolean semantics. If the param @sym@ is there without any value,</span>
133+<a name="line-124"></a><a name="HasServer"></a><span class='hs-comment'>-- or if it's there with value "true" or "1", it's interpreted as 'True'.</span>
134+<a name="line-125"></a><a name="HasServer"></a><span class='hs-comment'>-- Otherwise, it's interpreted as 'False'.</span>
135+<a name="line-126"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
136+<a name="line-127"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
137+<a name="line-128"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
138+<a name="line-129"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- /books?published</span>
139+<a name="line-130"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryFlag "published" :&gt; Get [Book]</span>
140+<a name="line-131"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span>
141+<a name="line-132"></a>
142+<a name="line-133"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use @'QueryFlag' "published"@ in one of the endpoints for your API,</span>
143+<a name="line-134"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
144+<a name="line-135"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of type 'Bool'.</span>
145+<a name="line-136"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
146+<a name="line-137"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
147+<a name="line-138"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
148+<a name="line-139"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; QueryFlag "published" :&gt; Get [Book]</span>
149+<a name="line-140"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt;</span>
150+<a name="line-141"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
151+<a name="line-142"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server = getBooks</span>
152+<a name="line-143"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; where getBooks :: Bool -&gt; EitherT (Int, String) IO [Book]</span>
153+<a name="line-144"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; getBooks onlyPublished = ...return all books, or only the ones that are already published, depending on the argument...</span>
154+<a name="line-145"></a><a name="instance%20HasServer%20(QueryFlag%20sym%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>sym</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
155+<a name="line-146"></a> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
156+<a name="line-147"></a>
157+<a name="line-148"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryFlag</span> <span class='hs-varid'>sym</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
158+<a name="line-149"></a> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
159+<a name="line-150"></a>
160+<a name="line-151"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
161+<a name="line-152"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>querytext</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parseQueryText</span> <span class='hs-varop'>$</span> <span class='hs-varid'>rawQueryString</span> <span class='hs-varid'>request</span>
162+<a name="line-153"></a> <span class='hs-varid'>param</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>paramname</span> <span class='hs-varid'>querytext</span> <span class='hs-keyword'>of</span>
163+<a name="line-154"></a> <span class='hs-conid'>Just</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>True</span> <span class='hs-comment'>-- param is there, with no value</span>
164+<a name="line-155"></a> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>examine</span> <span class='hs-varid'>v</span> <span class='hs-comment'>-- param with a value</span>
165+<a name="line-156"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>False</span> <span class='hs-comment'>-- param not in the query string</span>
166+<a name="line-157"></a>
167+<a name="line-158"></a> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>param</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
168+<a name="line-159"></a>
169+<a name="line-160"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>paramname</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>$</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sym</span><span class='hs-layout'>)</span>
170+<a name="line-161"></a> <span class='hs-varid'>examine</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>"true"</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>"1"</span> <span class='hs-varop'>||</span> <span class='hs-varid'>v</span> <span class='hs-varop'>==</span> <span class='hs-str'>""</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
171+<a name="line-162"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
172+</pre></body>
173+</html>
src/Servant-API-Raw.htmlnew file+43
@@ -0,0 +1,43 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Raw.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE InstanceSigs #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
13+<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span> <span class='hs-keyword'>where</span>
14+<a name="line-5"></a>
15+<a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
18+<a name="line-9"></a>
19+<a name="line-10"></a><a name="Raw"></a><span class='hs-comment'>-- | Endpoint for plugging in your own Wai 'Application's.</span>
20+<a name="line-11"></a><a name="Raw"></a><span class='hs-comment'>--</span>
21+<a name="line-12"></a><a name="Raw"></a><span class='hs-comment'>-- The given 'Application' will get the request as received by the server, potentially with</span>
22+<a name="line-13"></a><a name="Raw"></a><span class='hs-comment'>-- a modified (stripped) 'pathInfo' if the 'Application' is being routed with 'Servant.API.Sub.:&gt;'.</span>
23+<a name="line-14"></a><a name="Raw"></a><span class='hs-comment'>--</span>
24+<a name="line-15"></a><a name="Raw"></a><span class='hs-comment'>-- In addition to just letting you plug in your existing WAI 'Application's,</span>
25+<a name="line-16"></a><a name="Raw"></a><span class='hs-comment'>-- this can also be used with 'Servant.Utils.StaticFiles.serveDirectory' to serve</span>
26+<a name="line-17"></a><a name="Raw"></a><span class='hs-comment'>-- static files stored in a particular directory on your filesystem, or to serve</span>
27+<a name="line-18"></a><a name="Raw"></a><span class='hs-comment'>-- your API's documentation with 'Servant.Utils.StaticFiles.serveDocumentation'.</span>
28+<a name="line-19"></a><a name="Raw"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Raw</span>
29+<a name="line-20"></a>
30+<a name="line-21"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- | Just pass the request to the underlying application and serve its response.</span>
31+<a name="line-22"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>--</span>
32+<a name="line-23"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- Example:</span>
33+<a name="line-24"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>--</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- &gt; type MyApi = "images" :&gt; Raw</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- &gt;</span>
36+<a name="line-27"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-comment'>-- &gt; server = serveDirectory "/var/www/images"</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20Raw"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>HasServer</span> <span class='hs-conid'>Raw</span> <span class='hs-keyword'>where</span>
39+<a name="line-30"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Raw</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Application</span>
40+<a name="line-31"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>rawApplication</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span>
41+<a name="line-32"></a> <span class='hs-varid'>rawApplication</span> <span class='hs-varid'>request</span> <span class='hs-layout'>(</span><span class='hs-varid'>respond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>succeedWith</span><span class='hs-layout'>)</span>
42+</pre></body>
43+</html>
src/Servant-API-ReqBody.htmlnew file+60
@@ -0,0 +1,60 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/ReqBody.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
14+<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
15+<a name="line-6"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span> <span class='hs-keyword'>where</span>
16+<a name="line-7"></a>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Aeson</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
23+<a name="line-14"></a>
24+<a name="line-15"></a><a name="HasServer"></a><span class='hs-comment'>-- | Extract the request body as a value of type @a@.</span>
25+<a name="line-16"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
26+<a name="line-17"></a><a name="HasServer"></a><span class='hs-comment'>-- Example:</span>
27+<a name="line-18"></a><a name="HasServer"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; -- POST /books</span>
29+<a name="line-20"></a><a name="HasServer"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; ReqBody Book :&gt; Post Book</span>
30+<a name="line-21"></a><a name="HasServer"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span>
31+<a name="line-22"></a>
32+<a name="line-23"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | If you use 'ReqBody' in one of the endpoints for your API,</span>
33+<a name="line-24"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- this automatically requires your server-side handler to be a function</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- that takes an argument of the type specified by 'ReqBody'.</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- This lets servant worry about extracting it from the request and turning</span>
36+<a name="line-27"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- it into a value of the type you specify.</span>
37+<a name="line-28"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
38+<a name="line-29"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- All it asks is for a 'FromJSON' instance.</span>
39+<a name="line-30"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
40+<a name="line-31"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- Example:</span>
41+<a name="line-32"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>--</span>
42+<a name="line-33"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; ReqBody Book :&gt; Post Book</span>
43+<a name="line-34"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt;</span>
44+<a name="line-35"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
45+<a name="line-36"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; server = postBook</span>
46+<a name="line-37"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; where postBook :: Book -&gt; EitherT (Int, String) IO Book</span>
47+<a name="line-38"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-comment'>-- &gt; postBook book = ...insert into your db...</span>
48+<a name="line-39"></a><a name="instance%20HasServer%20(ReqBody%20a%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>FromJSON</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span>
49+<a name="line-40"></a> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
50+<a name="line-41"></a>
51+<a name="line-42"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
52+<a name="line-43"></a> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
53+<a name="line-44"></a>
54+<a name="line-45"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
55+<a name="line-46"></a> <span class='hs-varid'>mrqbody</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>decode'</span> <span class='hs-varop'>&lt;$&gt;</span> <span class='hs-varid'>lazyRequestBody</span> <span class='hs-varid'>request</span>
56+<a name="line-47"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>mrqbody</span> <span class='hs-keyword'>of</span>
57+<a name="line-48"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>InvalidBody</span>
58+<a name="line-49"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>v</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>subserver</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span>
59+</pre></body>
60+</html>
src/Servant-API-Sub.htmlnew file+47
@@ -0,0 +1,47 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API/Sub.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span> <span class='hs-keyword'>where</span>
15+<a name="line-6"></a>
16+<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
21+<a name="line-12"></a>
22+<a name="line-13"></a><span class='hs-comment'>-- | The contained API (second argument) can be found under @("/" ++ path)@</span>
23+<a name="line-14"></a><span class='hs-comment'>-- (path being the first argument).</span>
24+<a name="line-15"></a><span class='hs-comment'>--</span>
25+<a name="line-16"></a><span class='hs-comment'>-- Example:</span>
26+<a name="line-17"></a><span class='hs-comment'>--</span>
27+<a name="line-18"></a><span class='hs-comment'>-- &gt; -- GET /hello/world</span>
28+<a name="line-19"></a><span class='hs-comment'>-- &gt; -- returning a JSON encoded World value</span>
29+<a name="line-20"></a><span class='hs-comment'>-- &gt; type MyApi = "hello" :&gt; "world" :&gt; Get World</span>
30+<a name="line-21"></a><span class='hs-keyword'>data</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>path</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>a</span>
31+<a name="line-22"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>9</span> <span class='hs-conop'>:&gt;</span>
32+<a name="line-23"></a>
33+<a name="line-24"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-comment'>-- | Make sure the incoming request starts with @"/path"@, strip it and</span>
34+<a name="line-25"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-comment'>-- pass the rest of the request path to @sublayout@.</span>
35+<a name="line-26"></a><a name="instance%20HasServer%20(path%20:%3e%20sublayout)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>path</span><span class='hs-layout'>,</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>HasServer</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
36+<a name="line-27"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-layout'>(</span><span class='hs-varid'>path</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>sublayout</span>
37+<a name="line-28"></a> <span class='hs-varid'>route</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>pathInfo</span> <span class='hs-varid'>request</span> <span class='hs-keyword'>of</span>
38+<a name="line-29"></a> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-conop'>:</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span>
39+<a name="line-30"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>first</span> <span class='hs-varop'>==</span> <span class='hs-varid'>cs</span> <span class='hs-layout'>(</span><span class='hs-varid'>symbolVal</span> <span class='hs-varid'>proxyPath</span><span class='hs-layout'>)</span>
40+<a name="line-31"></a> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>route</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>sublayout</span><span class='hs-layout'>)</span> <span class='hs-varid'>subserver</span> <span class='hs-varid'>request</span><span class='hs-layout'>{</span>
41+<a name="line-32"></a> <span class='hs-varid'>pathInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rest</span>
42+<a name="line-33"></a> <span class='hs-layout'>}</span> <span class='hs-varid'>respond</span>
43+<a name="line-34"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>failWith</span> <span class='hs-conid'>NotFound</span>
44+<a name="line-35"></a>
45+<a name="line-36"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>proxyPath</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>path</span>
46+</pre></body>
47+</html>
src/Servant-API.htmlnew file+62
@@ -0,0 +1,62 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/API.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span> <span class='hs-layout'>(</span>
11+<a name="line-2"></a>
12+<a name="line-3"></a> <span class='hs-comment'>-- * Combinators</span>
13+<a name="line-4"></a> <span class='hs-comment'>-- | Type-level combinator for expressing subrouting: @':&gt;'@</span>
14+<a name="line-5"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span><span class='hs-layout'>,</span>
15+<a name="line-6"></a> <span class='hs-comment'>-- | Type-level combinator for alternative endpoints: @':&lt;|&gt;'@</span>
16+<a name="line-7"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span><span class='hs-layout'>,</span>
17+<a name="line-8"></a>
18+<a name="line-9"></a> <span class='hs-comment'>-- * Accessing information from the request</span>
19+<a name="line-10"></a> <span class='hs-comment'>-- | Capturing parts of the url path as parsed values: @'Capture'@</span>
20+<a name="line-11"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span><span class='hs-layout'>,</span>
21+<a name="line-12"></a> <span class='hs-comment'>-- | Retrieving parameters from the query string of the 'URI': @'QueryParam'@</span>
22+<a name="line-13"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span><span class='hs-layout'>,</span>
23+<a name="line-14"></a> <span class='hs-comment'>-- | Accessing the request body as a JSON-encoded type: @'ReqBody'@</span>
24+<a name="line-15"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span><span class='hs-layout'>,</span>
25+<a name="line-16"></a>
26+<a name="line-17"></a> <span class='hs-comment'>-- * Actual endpoints, distinguished by HTTP method</span>
27+<a name="line-18"></a> <span class='hs-comment'>-- | GET requests</span>
28+<a name="line-19"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span><span class='hs-layout'>,</span>
29+<a name="line-20"></a> <span class='hs-comment'>-- | POST requests</span>
30+<a name="line-21"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span><span class='hs-layout'>,</span>
31+<a name="line-22"></a> <span class='hs-comment'>-- | DELETE requests</span>
32+<a name="line-23"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span><span class='hs-layout'>,</span>
33+<a name="line-24"></a> <span class='hs-comment'>-- | PUT requests</span>
34+<a name="line-25"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span><span class='hs-layout'>,</span>
35+<a name="line-26"></a>
36+<a name="line-27"></a> <span class='hs-comment'>-- * Untyped endpoints</span>
37+<a name="line-28"></a> <span class='hs-comment'>-- | Plugging in a wai 'Network.Wai.Application', serving directories</span>
38+<a name="line-29"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span><span class='hs-layout'>,</span>
39+<a name="line-30"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span><span class='hs-layout'>,</span>
40+<a name="line-31"></a>
41+<a name="line-32"></a> <span class='hs-comment'>-- * Utilities</span>
42+<a name="line-33"></a> <span class='hs-comment'>-- | QuasiQuotes for endpoints</span>
43+<a name="line-34"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span><span class='hs-layout'>,</span>
44+<a name="line-35"></a> <span class='hs-comment'>-- | Type-safe internal URLs</span>
45+<a name="line-36"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span><span class='hs-layout'>,</span>
46+<a name="line-37"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
47+<a name="line-38"></a>
48+<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
49+<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
50+<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
51+<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
52+<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
53+<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
54+<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
55+<a name="line-46"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span>
56+<a name="line-47"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
57+<a name="line-48"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
58+<a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span> <span class='hs-layout'>(</span><span class='hs-varid'>sitemap</span><span class='hs-layout'>)</span>
59+<a name="line-50"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkLink</span><span class='hs-layout'>)</span>
60+<a name="line-51"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span>
61+</pre></body>
62+</html>
src/Servant-Common-Text.htmlnew file+141
@@ -0,0 +1,141 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/Common/Text.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE TypeSynonymInstances #-}</span>
13+<a name="line-4"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
14+<a name="line-5"></a> <span class='hs-layout'>(</span> <span class='hs-conid'>FromText</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
15+<a name="line-6"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>ToText</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span>
16+<a name="line-7"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
17+<a name="line-8"></a>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>String</span><span class='hs-varop'>.</span><span class='hs-conid'>Conversions</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span><span class='hs-varop'>.</span><span class='hs-conid'>Read</span>
22+<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Word</span>
23+<a name="line-14"></a>
24+<a name="line-15"></a><a name="FromText"></a><span class='hs-comment'>-- | For getting values from url captures and query string parameters</span>
25+<a name="line-16"></a><a name="FromText"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>FromText</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
26+<a name="line-17"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
27+<a name="line-18"></a>
28+<a name="line-19"></a><a name="ToText"></a><span class='hs-comment'>-- | For putting values in paths and query string parameters</span>
29+<a name="line-20"></a><a name="ToText"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ToText</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span>
30+<a name="line-21"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Text</span>
31+<a name="line-22"></a>
32+<a name="line-23"></a><a name="instance%20FromText%20Text"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Text</span> <span class='hs-keyword'>where</span>
33+<a name="line-24"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span>
34+<a name="line-25"></a>
35+<a name="line-26"></a><a name="instance%20ToText%20Text"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Text</span> <span class='hs-keyword'>where</span>
36+<a name="line-27"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id</span>
37+<a name="line-28"></a>
38+<a name="line-29"></a><a name="instance%20FromText%20String"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>where</span>
39+<a name="line-30"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-varid'>cs</span>
40+<a name="line-31"></a>
41+<a name="line-32"></a><a name="instance%20ToText%20String"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>where</span>
42+<a name="line-33"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span>
43+<a name="line-34"></a>
44+<a name="line-35"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- |</span>
45+<a name="line-36"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- &gt; fromText "true" = Just True</span>
46+<a name="line-37"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- &gt; fromText "false" = Just False</span>
47+<a name="line-38"></a><a name="instance%20FromText%20Bool"></a><span class='hs-comment'>-- &gt; fromText _ = Nothing</span>
48+<a name="line-39"></a><a name="instance%20FromText%20Bool"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>where</span>
49+<a name="line-40"></a> <span class='hs-varid'>fromText</span> <span class='hs-str'>"true"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-conid'>True</span>
50+<a name="line-41"></a> <span class='hs-varid'>fromText</span> <span class='hs-str'>"false"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-conid'>False</span>
51+<a name="line-42"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
52+<a name="line-43"></a>
53+<a name="line-44"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- |</span>
54+<a name="line-45"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- &gt; toText True = "true"</span>
55+<a name="line-46"></a><a name="instance%20ToText%20Bool"></a><span class='hs-comment'>-- &gt; toText False = "false"</span>
56+<a name="line-47"></a><a name="instance%20ToText%20Bool"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>where</span>
57+<a name="line-48"></a> <span class='hs-varid'>toText</span> <span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"true"</span>
58+<a name="line-49"></a> <span class='hs-varid'>toText</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"false"</span>
59+<a name="line-50"></a>
60+<a name="line-51"></a><a name="instance%20FromText%20Int"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>where</span>
61+<a name="line-52"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
62+<a name="line-53"></a>
63+<a name="line-54"></a><a name="instance%20ToText%20Int"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>where</span>
64+<a name="line-55"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
65+<a name="line-56"></a>
66+<a name="line-57"></a><a name="instance%20FromText%20Int8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int8</span> <span class='hs-keyword'>where</span>
67+<a name="line-58"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
68+<a name="line-59"></a>
69+<a name="line-60"></a><a name="instance%20ToText%20Int8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int8</span> <span class='hs-keyword'>where</span>
70+<a name="line-61"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
71+<a name="line-62"></a>
72+<a name="line-63"></a><a name="instance%20FromText%20Int16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int16</span> <span class='hs-keyword'>where</span>
73+<a name="line-64"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
74+<a name="line-65"></a>
75+<a name="line-66"></a><a name="instance%20ToText%20Int16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int16</span> <span class='hs-keyword'>where</span>
76+<a name="line-67"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
77+<a name="line-68"></a>
78+<a name="line-69"></a><a name="instance%20FromText%20Int32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int32</span> <span class='hs-keyword'>where</span>
79+<a name="line-70"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
80+<a name="line-71"></a>
81+<a name="line-72"></a><a name="instance%20ToText%20Int32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int32</span> <span class='hs-keyword'>where</span>
82+<a name="line-73"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
83+<a name="line-74"></a>
84+<a name="line-75"></a><a name="instance%20FromText%20Int64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Int64</span> <span class='hs-keyword'>where</span>
85+<a name="line-76"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-layout'>(</span><span class='hs-varid'>signed</span> <span class='hs-varid'>decimal</span><span class='hs-layout'>)</span>
86+<a name="line-77"></a>
87+<a name="line-78"></a><a name="instance%20ToText%20Int64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Int64</span> <span class='hs-keyword'>where</span>
88+<a name="line-79"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
89+<a name="line-80"></a>
90+<a name="line-81"></a><a name="instance%20FromText%20Word"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word</span> <span class='hs-keyword'>where</span>
91+<a name="line-82"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
92+<a name="line-83"></a>
93+<a name="line-84"></a><a name="instance%20ToText%20Word"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word</span> <span class='hs-keyword'>where</span>
94+<a name="line-85"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
95+<a name="line-86"></a>
96+<a name="line-87"></a><a name="instance%20FromText%20Word8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word8</span> <span class='hs-keyword'>where</span>
97+<a name="line-88"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
98+<a name="line-89"></a>
99+<a name="line-90"></a><a name="instance%20ToText%20Word8"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word8</span> <span class='hs-keyword'>where</span>
100+<a name="line-91"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
101+<a name="line-92"></a>
102+<a name="line-93"></a><a name="instance%20FromText%20Word16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word16</span> <span class='hs-keyword'>where</span>
103+<a name="line-94"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
104+<a name="line-95"></a>
105+<a name="line-96"></a><a name="instance%20ToText%20Word16"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word16</span> <span class='hs-keyword'>where</span>
106+<a name="line-97"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
107+<a name="line-98"></a>
108+<a name="line-99"></a><a name="instance%20FromText%20Word32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word32</span> <span class='hs-keyword'>where</span>
109+<a name="line-100"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
110+<a name="line-101"></a>
111+<a name="line-102"></a><a name="instance%20ToText%20Word32"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word32</span> <span class='hs-keyword'>where</span>
112+<a name="line-103"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
113+<a name="line-104"></a>
114+<a name="line-105"></a><a name="instance%20FromText%20Word64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Word64</span> <span class='hs-keyword'>where</span>
115+<a name="line-106"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
116+<a name="line-107"></a>
117+<a name="line-108"></a><a name="instance%20ToText%20Word64"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Word64</span> <span class='hs-keyword'>where</span>
118+<a name="line-109"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
119+<a name="line-110"></a>
120+<a name="line-111"></a><a name="instance%20FromText%20Integer"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Integer</span> <span class='hs-keyword'>where</span>
121+<a name="line-112"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>decimal</span>
122+<a name="line-113"></a>
123+<a name="line-114"></a><a name="instance%20ToText%20Integer"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Integer</span> <span class='hs-keyword'>where</span>
124+<a name="line-115"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
125+<a name="line-116"></a>
126+<a name="line-117"></a><a name="instance%20FromText%20Double"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Double</span> <span class='hs-keyword'>where</span>
127+<a name="line-118"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>rational</span>
128+<a name="line-119"></a>
129+<a name="line-120"></a><a name="instance%20ToText%20Double"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Double</span> <span class='hs-keyword'>where</span>
130+<a name="line-121"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
131+<a name="line-122"></a>
132+<a name="line-123"></a><a name="instance%20FromText%20Float"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>FromText</span> <span class='hs-conid'>Float</span> <span class='hs-keyword'>where</span>
133+<a name="line-124"></a> <span class='hs-varid'>fromText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>runReader</span> <span class='hs-varid'>rational</span>
134+<a name="line-125"></a>
135+<a name="line-126"></a><a name="instance%20ToText%20Float"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ToText</span> <span class='hs-conid'>Float</span> <span class='hs-keyword'>where</span>
136+<a name="line-127"></a> <span class='hs-varid'>toText</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cs</span> <span class='hs-varop'>.</span> <span class='hs-varid'>show</span>
137+<a name="line-128"></a>
138+<a name="line-129"></a><a name="runReader"></a><span class='hs-definition'>runReader</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Reader</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Text</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-varid'>a</span>
139+<a name="line-130"></a><span class='hs-definition'>runReader</span> <span class='hs-varid'>reader</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>either</span> <span class='hs-layout'>(</span><span class='hs-varid'>const</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varop'>.</span> <span class='hs-varid'>fst</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>reader</span> <span class='hs-varid'>t</span>
140+</pre></body>
141+</html>
src/Servant-QQ.htmlnew file+209
@@ -0,0 +1,209 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/QQ.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE MultiParamTypeClasses #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE FunctionalDependencies #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE DataKinds #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
14+<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
15+<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE TemplateHaskell #-}</span>
16+<a name="line-7"></a><span class='hs-comment'>{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}</span>
17+<a name="line-8"></a><span class='hs-comment'>-- | QuasiQuoting utilities for API types.</span>
18+<a name="line-9"></a><span class='hs-comment'>--</span>
19+<a name="line-10"></a><span class='hs-comment'>-- 'sitemap' allows you to write your type in a very natural way:</span>
20+<a name="line-11"></a><span class='hs-comment'>--</span>
21+<a name="line-12"></a><span class='hs-comment'>-- @</span>
22+<a name="line-13"></a><span class='hs-comment'>-- [sitemap|</span>
23+<a name="line-14"></a><span class='hs-comment'>-- PUT hello String -&gt; ()</span>
24+<a name="line-15"></a><span class='hs-comment'>-- POST hello/p:Int String -&gt; ()</span>
25+<a name="line-16"></a><span class='hs-comment'>-- GET hello/?name:String Int</span>
26+<a name="line-17"></a><span class='hs-comment'>-- |]</span>
27+<a name="line-18"></a><span class='hs-comment'>-- @</span>
28+<a name="line-19"></a><span class='hs-comment'>--</span>
29+<a name="line-20"></a><span class='hs-comment'>-- Will generate:</span>
30+<a name="line-21"></a><span class='hs-comment'>--</span>
31+<a name="line-22"></a><span class='hs-comment'>-- @</span>
32+<a name="line-23"></a><span class='hs-comment'>-- "hello" :&gt; ReqBody String :&gt; Put ()</span>
33+<a name="line-24"></a><span class='hs-comment'>-- :\&lt;|&gt; "hello" :&gt; Capture "p" Int :&gt; ReqBody String :&gt; Post ()</span>
34+<a name="line-25"></a><span class='hs-comment'>-- :\&lt;|&gt; "hello" :&gt; QueryParam "name" String :&gt; Get Int</span>
35+<a name="line-26"></a><span class='hs-comment'>-- @</span>
36+<a name="line-27"></a><span class='hs-comment'>--</span>
37+<a name="line-28"></a><span class='hs-comment'>-- Note the @/@ before a @QueryParam@!</span>
38+<a name="line-29"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span> <span class='hs-keyword'>where</span>
39+<a name="line-30"></a>
40+<a name="line-31"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span> <span class='hs-layout'>(</span><span class='hs-varid'>void</span><span class='hs-layout'>)</span>
41+<a name="line-32"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Applicative</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>many</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>&lt;|&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>optional</span><span class='hs-layout'>)</span>
42+<a name="line-33"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>TH</span><span class='hs-varop'>.</span><span class='hs-conid'>Quote</span>
43+<a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Language</span><span class='hs-varop'>.</span><span class='hs-conid'>Haskell</span><span class='hs-varop'>.</span><span class='hs-conid'>TH</span>
44+<a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Text</span><span class='hs-varop'>.</span><span class='hs-conid'>ParserCombinators</span><span class='hs-varop'>.</span><span class='hs-conid'>Parsec</span>
45+<a name="line-36"></a>
46+<a name="line-37"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
47+<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
48+<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
49+<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
50+<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
51+<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
52+<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
53+<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
54+<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
55+<a name="line-46"></a>
56+<a name="line-47"></a><a name="ExpSYM"></a><span class='hs-comment'>-- | Finally-tagless encoding for our DSL.</span>
57+<a name="line-48"></a><a name="ExpSYM"></a><span class='hs-comment'>-- Keeping 'repr'' and 'repr' distinct when writing functions with an</span>
58+<a name="line-49"></a><a name="ExpSYM"></a><span class='hs-comment'>-- @ExpSYM@ context ensures certain invariants (for instance, that there is</span>
59+<a name="line-50"></a><a name="ExpSYM"></a><span class='hs-comment'>-- only one of 'get', 'post', 'put', and 'delete' in a value), but</span>
60+<a name="line-51"></a><a name="ExpSYM"></a><span class='hs-comment'>-- sometimes requires a little more work.</span>
61+<a name="line-52"></a><a name="ExpSYM"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr'</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr'</span><span class='hs-layout'>,</span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span> <span class='hs-keyword'>where</span>
62+<a name="line-53"></a> <span class='hs-varid'>lit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
63+<a name="line-54"></a> <span class='hs-varid'>capture</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
64+<a name="line-55"></a> <span class='hs-varid'>reqBody</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
65+<a name="line-56"></a> <span class='hs-varid'>queryParam</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
66+<a name="line-57"></a> <span class='hs-varid'>conj</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>repr'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
67+<a name="line-58"></a> <span class='hs-varid'>get</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
68+<a name="line-59"></a> <span class='hs-varid'>post</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
69+<a name="line-60"></a> <span class='hs-varid'>put</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
70+<a name="line-61"></a> <span class='hs-varid'>delete</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span>
71+<a name="line-62"></a>
72+<a name="line-63"></a>
73+<a name="line-64"></a><span class='hs-keyword'>infixr</span> <span class='hs-num'>6</span> <span class='hs-varop'>&gt;:</span>
74+<a name="line-65"></a>
75+<a name="line-66"></a><a name="%3e:"></a><span class='hs-layout'>(</span><span class='hs-varop'>&gt;:</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>
76+<a name="line-67"></a><span class='hs-layout'>(</span><span class='hs-varop'>&gt;:</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>conj</span>
77+<a name="line-68"></a>
78+<a name="line-69"></a>
79+<a name="line-70"></a><a name="instance%20ExpSYM%20Type%20Type"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-conid'>Type</span> <span class='hs-conid'>Type</span> <span class='hs-keyword'>where</span>
80+<a name="line-71"></a> <span class='hs-varid'>lit</span> <span class='hs-varid'>name</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;:</span> <span class='hs-varid'>r</span>
81+<a name="line-72"></a> <span class='hs-varid'>capture</span> <span class='hs-varid'>name</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Capture</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
82+<a name="line-73"></a> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;:</span> <span class='hs-varid'>r</span>
83+<a name="line-74"></a> <span class='hs-varid'>reqBody</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>ReqBody</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;:</span> <span class='hs-varid'>r</span>
84+<a name="line-75"></a> <span class='hs-varid'>queryParam</span> <span class='hs-varid'>name</span> <span class='hs-varid'>typ</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>QueryParam</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LitT</span> <span class='hs-layout'>(</span><span class='hs-conid'>StrTyLit</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
85+<a name="line-76"></a> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;:</span> <span class='hs-varid'>r</span>
86+<a name="line-77"></a> <span class='hs-varid'>conj</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-layout'>(</span><span class='hs-conop'>:&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
87+<a name="line-78"></a> <span class='hs-varid'>get</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Get</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
88+<a name="line-79"></a> <span class='hs-varid'>post</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Post</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
89+<a name="line-80"></a> <span class='hs-varid'>put</span> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Put</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkName</span> <span class='hs-varid'>typ</span><span class='hs-layout'>)</span>
90+<a name="line-81"></a> <span class='hs-varid'>delete</span> <span class='hs-str'>"()"</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-conid'>Delete</span>
91+<a name="line-82"></a> <span class='hs-varid'>delete</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-str'>"Delete does not return a request body"</span>
92+<a name="line-83"></a>
93+<a name="line-84"></a><a name="parseMethod"></a><span class='hs-definition'>parseMethod</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr'</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
94+<a name="line-85"></a><span class='hs-definition'>parseMethod</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"GET"</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>get</span><span class='hs-layout'>)</span>
95+<a name="line-86"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"POST"</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>post</span><span class='hs-layout'>)</span>
96+<a name="line-87"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"PUT"</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>put</span><span class='hs-layout'>)</span>
97+<a name="line-88"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"DELETE"</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>delete</span><span class='hs-layout'>)</span>
98+<a name="line-89"></a>
99+<a name="line-90"></a><a name="parseUrlSegment"></a><span class='hs-definition'>parseUrlSegment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
100+<a name="line-91"></a><span class='hs-definition'>parseUrlSegment</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseCapture</span>
101+<a name="line-92"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseQueryParam</span>
102+<a name="line-93"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-varid'>parseLit</span>
103+<a name="line-94"></a> <span class='hs-keyword'>where</span>
104+<a name="line-95"></a> <span class='hs-varid'>parseCapture</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
105+<a name="line-96"></a> <span class='hs-varid'>cname</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
106+<a name="line-97"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>':'</span>
107+<a name="line-98"></a> <span class='hs-varid'>ctyp</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
108+<a name="line-99"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>capture</span> <span class='hs-varid'>cname</span> <span class='hs-varid'>ctyp</span>
109+<a name="line-100"></a> <span class='hs-varid'>parseQueryParam</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
110+<a name="line-101"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>'?'</span>
111+<a name="line-102"></a> <span class='hs-varid'>cname</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
112+<a name="line-103"></a> <span class='hs-varid'>char</span> <span class='hs-chr'>':'</span>
113+<a name="line-104"></a> <span class='hs-varid'>ctyp</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
114+<a name="line-105"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>queryParam</span> <span class='hs-varid'>cname</span> <span class='hs-varid'>ctyp</span>
115+<a name="line-106"></a> <span class='hs-varid'>parseLit</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lit</span> <span class='hs-varop'>&lt;$&gt;</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>" ?/:"</span><span class='hs-layout'>)</span>
116+<a name="line-107"></a>
117+<a name="line-108"></a><a name="parseUrl"></a><span class='hs-definition'>parseUrl</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Parser</span> <span class='hs-layout'>(</span><span class='hs-varid'>repr</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>repr</span><span class='hs-layout'>)</span>
118+<a name="line-109"></a><span class='hs-definition'>parseUrl</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
119+<a name="line-110"></a> <span class='hs-varid'>optional</span> <span class='hs-varop'>$</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'/'</span>
120+<a name="line-111"></a> <span class='hs-varid'>url</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>parseUrlSegment</span> <span class='hs-varop'>`sepBy1`</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'/'</span>
121+<a name="line-112"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>foldr1</span> <span class='hs-layout'>(</span><span class='hs-varop'>.</span><span class='hs-layout'>)</span> <span class='hs-varid'>url</span>
122+<a name="line-113"></a>
123+<a name="line-114"></a><a name="Typ"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Typ</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Val</span> <span class='hs-conid'>String</span>
124+<a name="line-115"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReqArgVal</span> <span class='hs-conid'>String</span> <span class='hs-conid'>String</span>
125+<a name="line-116"></a>
126+<a name="line-117"></a><a name="parseTyp"></a><span class='hs-definition'>parseTyp</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>Typ</span>
127+<a name="line-118"></a><span class='hs-definition'>parseTyp</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
128+<a name="line-119"></a> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>"-{\n\r"</span><span class='hs-layout'>)</span>
129+<a name="line-120"></a> <span class='hs-varid'>spaces</span>
130+<a name="line-121"></a> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>optionMaybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varid'>parseRet</span><span class='hs-layout'>)</span>
131+<a name="line-122"></a> <span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>optional</span> <span class='hs-varid'>inlineComment</span>
132+<a name="line-123"></a> <span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>optional</span> <span class='hs-varid'>blockComment</span>
133+<a name="line-124"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>of</span>
134+<a name="line-125"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Val</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span>
135+<a name="line-126"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>s'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>ReqArgVal</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>stripTr</span> <span class='hs-varid'>s'</span><span class='hs-layout'>)</span>
136+<a name="line-127"></a> <span class='hs-keyword'>where</span>
137+<a name="line-128"></a> <span class='hs-varid'>parseRet</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>String</span>
138+<a name="line-129"></a> <span class='hs-varid'>parseRet</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
139+<a name="line-130"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"-&gt;"</span>
140+<a name="line-131"></a> <span class='hs-varid'>spaces</span>
141+<a name="line-132"></a> <span class='hs-varid'>many</span> <span class='hs-layout'>(</span><span class='hs-varid'>noneOf</span> <span class='hs-str'>"-{\n\r"</span><span class='hs-layout'>)</span>
142+<a name="line-133"></a> <span class='hs-varid'>stripTr</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reverse</span> <span class='hs-varop'>.</span> <span class='hs-varid'>dropWhile</span> <span class='hs-layout'>(</span><span class='hs-varop'>==</span> <span class='hs-chr'>' '</span><span class='hs-layout'>)</span> <span class='hs-varop'>.</span> <span class='hs-varid'>reverse</span>
143+<a name="line-134"></a>
144+<a name="line-135"></a>
145+<a name="line-136"></a><a name="parseEntry"></a><span class='hs-definition'>parseEntry</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ExpSYM</span> <span class='hs-varid'>repr</span> <span class='hs-varid'>repr</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Parser</span> <span class='hs-varid'>repr</span>
146+<a name="line-137"></a><span class='hs-definition'>parseEntry</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
147+<a name="line-138"></a> <span class='hs-varid'>met</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>parseMethod</span>
148+<a name="line-139"></a> <span class='hs-varid'>spaces</span>
149+<a name="line-140"></a> <span class='hs-varid'>url</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>parseUrl</span>
150+<a name="line-141"></a> <span class='hs-varid'>spaces</span>
151+<a name="line-142"></a> <span class='hs-varid'>typ</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>parseTyp</span>
152+<a name="line-143"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>typ</span> <span class='hs-keyword'>of</span>
153+<a name="line-144"></a> <span class='hs-conid'>Val</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>url</span> <span class='hs-layout'>(</span><span class='hs-varid'>met</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>
154+<a name="line-145"></a> <span class='hs-conid'>ReqArgVal</span> <span class='hs-varid'>i</span> <span class='hs-varid'>o</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>url</span> <span class='hs-varop'>$</span> <span class='hs-varid'>reqBody</span> <span class='hs-varid'>i</span> <span class='hs-layout'>(</span><span class='hs-varid'>met</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span>
155+<a name="line-146"></a>
156+<a name="line-147"></a><a name="blockComment"></a><span class='hs-definition'>blockComment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
157+<a name="line-148"></a><span class='hs-definition'>blockComment</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
158+<a name="line-149"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"{-"</span>
159+<a name="line-150"></a> <span class='hs-varid'>manyTill</span> <span class='hs-varid'>anyChar</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>string</span> <span class='hs-str'>"-}"</span><span class='hs-layout'>)</span>
160+<a name="line-151"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
161+<a name="line-152"></a>
162+<a name="line-153"></a><a name="inlineComment"></a><span class='hs-definition'>inlineComment</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
163+<a name="line-154"></a><span class='hs-definition'>inlineComment</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
164+<a name="line-155"></a> <span class='hs-varid'>string</span> <span class='hs-str'>"--"</span>
165+<a name="line-156"></a> <span class='hs-varid'>manyTill</span> <span class='hs-varid'>anyChar</span> <span class='hs-layout'>(</span><span class='hs-varid'>try</span> <span class='hs-varop'>$</span> <span class='hs-varid'>lookAhead</span> <span class='hs-varid'>eol</span><span class='hs-layout'>)</span>
166+<a name="line-157"></a> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
167+<a name="line-158"></a>
168+<a name="line-159"></a><a name="eol"></a><span class='hs-definition'>eol</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>String</span>
169+<a name="line-160"></a><span class='hs-definition'>eol</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"\n\r"</span><span class='hs-layout'>)</span>
170+<a name="line-161"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>try</span> <span class='hs-layout'>(</span><span class='hs-varid'>string</span> <span class='hs-str'>"\r\n"</span><span class='hs-layout'>)</span>
171+<a name="line-162"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>string</span> <span class='hs-str'>"\n"</span>
172+<a name="line-163"></a> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>string</span> <span class='hs-str'>"\r"</span>
173+<a name="line-164"></a> <span class='hs-varop'>&lt;?&gt;</span> <span class='hs-str'>"end of line"</span>
174+<a name="line-165"></a>
175+<a name="line-166"></a><a name="eols"></a><span class='hs-definition'>eols</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>()</span>
176+<a name="line-167"></a><span class='hs-definition'>eols</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>skipMany</span> <span class='hs-varop'>$</span> <span class='hs-varid'>void</span> <span class='hs-varid'>eol</span> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>blockComment</span> <span class='hs-varop'>&lt;|&gt;</span> <span class='hs-varid'>inlineComment</span>
177+<a name="line-168"></a>
178+<a name="line-169"></a><a name="parseAll"></a><span class='hs-definition'>parseAll</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Parser</span> <span class='hs-conid'>Type</span>
179+<a name="line-170"></a><span class='hs-definition'>parseAll</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
180+<a name="line-171"></a> <span class='hs-varid'>eols</span>
181+<a name="line-172"></a> <span class='hs-varid'>entries</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>parseEntry</span> <span class='hs-varop'>`endBy`</span> <span class='hs-varid'>eols</span>
182+<a name="line-173"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>foldr1</span> <span class='hs-varid'>union</span> <span class='hs-varid'>entries</span>
183+<a name="line-174"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>union</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Type</span>
184+<a name="line-175"></a> <span class='hs-varid'>union</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>AppT</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConT</span> <span class='hs-chr'>'</span><span class='hs-chr'>'</span><span class='hs-layout'>(</span><span class='hs-conop'>:&lt;|&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
185+<a name="line-176"></a>
186+<a name="line-177"></a><a name="sitemap"></a><span class='hs-comment'>-- | The sitemap QuasiQuoter.</span>
187+<a name="line-178"></a><span class='hs-comment'>--</span>
188+<a name="line-179"></a><span class='hs-comment'>-- * @.../&lt;var&gt;:&lt;type&gt;/...@ becomes a capture</span>
189+<a name="line-180"></a><span class='hs-comment'>-- * @.../?&lt;var&gt;:&lt;type&gt;@ becomes a query parameter</span>
190+<a name="line-181"></a><span class='hs-comment'>-- * @&lt;method&gt; ... &lt;typ&gt;@ becomes a method returning @&lt;typ&gt;@</span>
191+<a name="line-182"></a><span class='hs-comment'>-- * @&lt;method&gt; ... &lt;typ1&gt; -&gt; &lt;typ2&gt;@ becomes a method with request</span>
192+<a name="line-183"></a><span class='hs-comment'>-- body of @&lt;typ1&gt;@ and returning @&lt;typ2&gt;@</span>
193+<a name="line-184"></a><span class='hs-comment'>--</span>
194+<a name="line-185"></a><span class='hs-comment'>-- Comments are allowed, and have the standard Haskell format</span>
195+<a name="line-186"></a><span class='hs-comment'>--</span>
196+<a name="line-187"></a><span class='hs-comment'>-- * @--@ for inline</span>
197+<a name="line-188"></a><span class='hs-comment'>-- * @{- ... -}@ for block</span>
198+<a name="line-189"></a><span class='hs-comment'>--</span>
199+<a name="line-190"></a><span class='hs-definition'>sitemap</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>QuasiQuoter</span>
200+<a name="line-191"></a><span class='hs-definition'>sitemap</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>QuasiQuoter</span> <span class='hs-layout'>{</span> <span class='hs-varid'>quoteExp</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
201+<a name="line-192"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quotePat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
202+<a name="line-193"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quoteType</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span><span class='hs-varid'>x</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>parse</span> <span class='hs-varid'>parseAll</span> <span class='hs-str'>""</span> <span class='hs-varid'>x</span> <span class='hs-keyword'>of</span>
203+<a name="line-194"></a> <span class='hs-conid'>Left</span> <span class='hs-varid'>err</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>error</span> <span class='hs-varop'>$</span> <span class='hs-varid'>show</span> <span class='hs-varid'>err</span>
204+<a name="line-195"></a> <span class='hs-conid'>Right</span> <span class='hs-varid'>st</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-varid'>st</span>
205+<a name="line-196"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>quoteDec</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
206+<a name="line-197"></a> <span class='hs-layout'>}</span>
207+<a name="line-198"></a>
208+</pre></body>
209+</html>
src/Servant-Server.htmlnew file+116
@@ -0,0 +1,116 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/Server.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE OverloadedStrings #-}</span>
12+<a name="line-3"></a>
13+<a name="line-4"></a><span class='hs-comment'>-- | This module lets you implement 'Server's for defined APIs. You'll</span>
14+<a name="line-5"></a><span class='hs-comment'>-- most likely just need 'serve'.</span>
15+<a name="line-6"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span> <span class='hs-keyword'>where</span>
16+<a name="line-7"></a>
17+<a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Monoid</span>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>HTTP</span><span class='hs-varop'>.</span><span class='hs-conid'>Types</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span>
21+<a name="line-12"></a>
22+<a name="line-13"></a><span class='hs-comment'>-- * Implementing Servers</span>
23+<a name="line-14"></a>
24+<a name="line-15"></a><a name="serve"></a><span class='hs-comment'>-- | 'serve' allows you to implement an API and produce a wai 'Application'.</span>
25+<a name="line-16"></a><span class='hs-comment'>--</span>
26+<a name="line-17"></a><span class='hs-comment'>-- Example:</span>
27+<a name="line-18"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><span class='hs-comment'>-- &gt; type MyApi = "books" :&gt; Get [Book] -- GET /books</span>
29+<a name="line-20"></a><span class='hs-comment'>-- &gt; :&lt;|&gt; "books" :&gt; ReqBody Book :&gt; Post Book -- POST /books</span>
30+<a name="line-21"></a><span class='hs-comment'>-- &gt;</span>
31+<a name="line-22"></a><span class='hs-comment'>-- &gt; server :: Server MyApi</span>
32+<a name="line-23"></a><span class='hs-comment'>-- &gt; server = listAllBooks :&lt;|&gt; postBook</span>
33+<a name="line-24"></a><span class='hs-comment'>-- &gt; where listAllBooks = ...</span>
34+<a name="line-25"></a><span class='hs-comment'>-- &gt; postBook book = ...</span>
35+<a name="line-26"></a><span class='hs-comment'>-- &gt;</span>
36+<a name="line-27"></a><span class='hs-comment'>-- &gt; app :: Application</span>
37+<a name="line-28"></a><span class='hs-comment'>-- &gt; app = serve myApi server</span>
38+<a name="line-29"></a><span class='hs-comment'>-- &gt;</span>
39+<a name="line-30"></a><span class='hs-comment'>-- &gt; main :: IO ()</span>
40+<a name="line-31"></a><span class='hs-comment'>-- &gt; main = Network.Wai.Handler.Warp.run 8080 app</span>
41+<a name="line-32"></a><span class='hs-definition'>serve</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Application</span>
42+<a name="line-33"></a><span class='hs-definition'>serve</span> <span class='hs-varid'>p</span> <span class='hs-varid'>server</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toApplication</span> <span class='hs-layout'>(</span><span class='hs-varid'>route</span> <span class='hs-varid'>p</span> <span class='hs-varid'>server</span><span class='hs-layout'>)</span>
43+<a name="line-34"></a>
44+<a name="line-35"></a><a name="toApplication"></a><span class='hs-definition'>toApplication</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RoutingApplication</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Application</span>
45+<a name="line-36"></a><span class='hs-definition'>toApplication</span> <span class='hs-varid'>ra</span> <span class='hs-varid'>request</span> <span class='hs-varid'>respond</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
46+<a name="line-37"></a> <span class='hs-varid'>ra</span> <span class='hs-varid'>request</span> <span class='hs-layout'>(</span><span class='hs-varid'>routingRespond</span> <span class='hs-varop'>.</span> <span class='hs-varid'>routeResult</span><span class='hs-layout'>)</span>
47+<a name="line-38"></a> <span class='hs-keyword'>where</span>
48+<a name="line-39"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Either</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span>
49+<a name="line-40"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>NotFound</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
50+<a name="line-41"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>notFound404</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"not found"</span>
51+<a name="line-42"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>WrongMethod</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
52+<a name="line-43"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>methodNotAllowed405</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"method not allowed"</span>
53+<a name="line-44"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-conid'>InvalidBody</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
54+<a name="line-45"></a> <span class='hs-varid'>respond</span> <span class='hs-varop'>$</span> <span class='hs-varid'>responseLBS</span> <span class='hs-varid'>badRequest400</span> <span class='hs-conid'>[]</span> <span class='hs-str'>"Invalid JSON in request body"</span>
55+<a name="line-46"></a> <span class='hs-varid'>routingRespond</span> <span class='hs-layout'>(</span><span class='hs-conid'>Right</span> <span class='hs-varid'>response</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
56+<a name="line-47"></a> <span class='hs-varid'>respond</span> <span class='hs-varid'>response</span>
57+<a name="line-48"></a>
58+<a name="line-49"></a><a name="RouteMismatch"></a><span class='hs-comment'>-- * Route mismatch</span>
59+<a name="line-50"></a><a name="RouteMismatch"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyglyph'>=</span>
60+<a name="line-51"></a> <span class='hs-conid'>NotFound</span> <span class='hs-comment'>-- ^ the usual "not found" error</span>
61+<a name="line-52"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>WrongMethod</span> <span class='hs-comment'>-- ^ a more informative "you just got the HTTP method wrong" error</span>
62+<a name="line-53"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>InvalidBody</span> <span class='hs-comment'>-- ^ an even more informative "your json request body wasn't valid" error</span>
63+<a name="line-54"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>,</span> <span class='hs-conid'>Show</span><span class='hs-layout'>)</span>
64+<a name="line-55"></a>
65+<a name="line-56"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- | </span>
66+<a name="line-57"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- @</span>
67+<a name="line-58"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt; mempty = NotFound</span>
68+<a name="line-59"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt;</span>
69+<a name="line-60"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt; NotFound `mappend` x = x</span>
70+<a name="line-61"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt; WrongMethod `mappend` InvalidBody = InvalidBody</span>
71+<a name="line-62"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt; WrongMethod `mappend` _ = WrongMethod</span>
72+<a name="line-63"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- &gt; InvalidBody `mappend` _ = InvalidBody</span>
73+<a name="line-64"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-comment'>-- @</span>
74+<a name="line-65"></a><a name="instance%20Monoid%20RouteMismatch"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Monoid</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyword'>where</span>
75+<a name="line-66"></a> <span class='hs-varid'>mempty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NotFound</span>
76+<a name="line-67"></a>
77+<a name="line-68"></a> <span class='hs-conid'>NotFound</span> <span class='hs-varop'>`mappend`</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span>
78+<a name="line-69"></a> <span class='hs-conid'>WrongMethod</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>InvalidBody</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>InvalidBody</span>
79+<a name="line-70"></a> <span class='hs-conid'>WrongMethod</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WrongMethod</span>
80+<a name="line-71"></a> <span class='hs-conid'>InvalidBody</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>InvalidBody</span>
81+<a name="line-72"></a>
82+<a name="line-73"></a><a name="RouteResult"></a><span class='hs-comment'>-- | A wrapper around @'Either' 'RouteMismatch' a@.</span>
83+<a name="line-74"></a><a name="RouteResult"></a><span class='hs-keyword'>newtype</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span>
84+<a name="line-75"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>{</span> <span class='hs-varid'>routeResult</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Either</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-varid'>a</span> <span class='hs-layout'>}</span>
85+<a name="line-76"></a> <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>,</span> <span class='hs-conid'>Show</span><span class='hs-layout'>)</span>
86+<a name="line-77"></a>
87+<a name="line-78"></a><a name="failWith"></a><span class='hs-definition'>failWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RouteMismatch</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span>
88+<a name="line-79"></a><span class='hs-definition'>failWith</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Left</span>
89+<a name="line-80"></a>
90+<a name="line-81"></a><a name="succeedWith"></a><span class='hs-definition'>succeedWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span>
91+<a name="line-82"></a><span class='hs-definition'>succeedWith</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>.</span> <span class='hs-conid'>Right</span>
92+<a name="line-83"></a>
93+<a name="line-84"></a><a name="isMismatch"></a><span class='hs-definition'>isMismatch</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
94+<a name="line-85"></a><span class='hs-definition'>isMismatch</span> <span class='hs-layout'>(</span><span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
95+<a name="line-86"></a><span class='hs-definition'>isMismatch</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
96+<a name="line-87"></a>
97+<a name="line-88"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- | If we get a `Right`, it has precedence over everything else.</span>
98+<a name="line-89"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>--</span>
99+<a name="line-90"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- This in particular means that if we could get several 'Right's,</span>
100+<a name="line-91"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-comment'>-- only the first we encounter would be taken into account.</span>
101+<a name="line-92"></a><a name="instance%20Monoid%20(RouteResult%20a)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Monoid</span> <span class='hs-layout'>(</span><span class='hs-conid'>RouteResult</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
102+<a name="line-93"></a> <span class='hs-varid'>mempty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Left</span> <span class='hs-varid'>mempty</span>
103+<a name="line-94"></a>
104+<a name="line-95"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Left</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span>
105+<a name="line-96"></a> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Left</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varop'>`mappend`</span> <span class='hs-conid'>RR</span> <span class='hs-layout'>(</span><span class='hs-conid'>Right</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>RR</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Right</span> <span class='hs-varid'>y</span>
106+<a name="line-97"></a> <span class='hs-varid'>r</span> <span class='hs-varop'>`mappend`</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>r</span>
107+<a name="line-98"></a>
108+<a name="line-99"></a><a name="RoutingApplication"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>RoutingApplication</span> <span class='hs-keyglyph'>=</span>
109+<a name="line-100"></a> <span class='hs-conid'>Request</span> <span class='hs-comment'>-- ^ the request, the field 'pathInfo' may be modified by url routing</span>
110+<a name="line-101"></a> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>RouteResult</span> <span class='hs-conid'>Response</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>ResponseReceived</span>
111+<a name="line-102"></a>
112+<a name="line-103"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>HasServer</span> <span class='hs-varid'>layout</span> <span class='hs-keyword'>where</span>
113+<a name="line-104"></a> <span class='hs-keyword'>type</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>*</span>
114+<a name="line-105"></a> <span class='hs-varid'>route</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-varid'>layout</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RoutingApplication</span>
115+</pre></body>
116+</html>
src/Servant-Utils-Links.htmlnew file+121
@@ -0,0 +1,121 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/Utils/Links.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE PolyKinds #-}</span>
11+<a name="line-2"></a><span class='hs-comment'>{-# LANGUAGE DataKinds #-}</span>
12+<a name="line-3"></a><span class='hs-comment'>{-# LANGUAGE FlexibleInstances #-}</span>
13+<a name="line-4"></a><span class='hs-comment'>{-# LANGUAGE TypeFamilies #-}</span>
14+<a name="line-5"></a><span class='hs-comment'>{-# LANGUAGE TypeOperators #-}</span>
15+<a name="line-6"></a><span class='hs-comment'>{-# LANGUAGE FunctionalDependencies #-}</span>
16+<a name="line-7"></a><span class='hs-comment'>{-# LANGUAGE ScopedTypeVariables #-}</span>
17+<a name="line-8"></a><span class='hs-comment'>{-# LANGUAGE UndecidableInstances #-}</span>
18+<a name="line-9"></a><span class='hs-comment'>-- | Type safe internal links.</span>
19+<a name="line-10"></a><span class='hs-comment'>--</span>
20+<a name="line-11"></a><span class='hs-comment'>-- Provides the function 'mkLink':</span>
21+<a name="line-12"></a><span class='hs-comment'>--</span>
22+<a name="line-13"></a><span class='hs-comment'>-- @</span>
23+<a name="line-14"></a><span class='hs-comment'>-- type API = Proxy ("hello" :&gt; Get Int</span>
24+<a name="line-15"></a><span class='hs-comment'>-- :&lt;|&gt; "bye" :&gt; QueryParam "name" String :&gt; Post Bool)</span>
25+<a name="line-16"></a><span class='hs-comment'>--</span>
26+<a name="line-17"></a><span class='hs-comment'>-- api :: API</span>
27+<a name="line-18"></a><span class='hs-comment'>-- api = proxy</span>
28+<a name="line-19"></a><span class='hs-comment'>--</span>
29+<a name="line-20"></a><span class='hs-comment'>-- link1 :: Proxy ("hello" :&gt; Get Int)</span>
30+<a name="line-21"></a><span class='hs-comment'>-- link1 = proxy</span>
31+<a name="line-22"></a><span class='hs-comment'>--</span>
32+<a name="line-23"></a><span class='hs-comment'>-- link2 :: Proxy ("hello" :&gt; Delete)</span>
33+<a name="line-24"></a><span class='hs-comment'>-- link2 = proxy</span>
34+<a name="line-25"></a><span class='hs-comment'>--</span>
35+<a name="line-26"></a><span class='hs-comment'>-- mkLink link1 API -- typechecks, returns 'Link "/hello"'</span>
36+<a name="line-27"></a><span class='hs-comment'>--</span>
37+<a name="line-28"></a><span class='hs-comment'>-- mkLink link2 API -- doesn't typecheck</span>
38+<a name="line-29"></a><span class='hs-comment'>-- @</span>
39+<a name="line-30"></a><span class='hs-comment'>--</span>
40+<a name="line-31"></a><span class='hs-comment'>-- That is, 'mkLink' takes two arguments, a link proxy and a sitemap, and</span>
41+<a name="line-32"></a><span class='hs-comment'>-- returns a 'Link', but only typechecks if the link proxy is a valid link,</span>
42+<a name="line-33"></a><span class='hs-comment'>-- and part of the sitemap.</span>
43+<a name="line-34"></a><span class='hs-comment'>--</span>
44+<a name="line-35"></a><span class='hs-comment'>-- __N.B.:__ 'mkLink' assumes a capture matches any string (without slashes).</span>
45+<a name="line-36"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span> <span class='hs-keyword'>where</span>
46+<a name="line-37"></a>
47+<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
48+<a name="line-39"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>TypeLits</span>
49+<a name="line-40"></a>
50+<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Capture</span>
51+<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>ReqBody</span>
52+<a name="line-43"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>QueryParam</span>
53+<a name="line-44"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Get</span>
54+<a name="line-45"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Post</span>
55+<a name="line-46"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Put</span>
56+<a name="line-47"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Delete</span>
57+<a name="line-48"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Sub</span>
58+<a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Alternative</span>
59+<a name="line-50"></a>
60+<a name="line-51"></a>
61+<a name="line-52"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>Or</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>where</span>
62+<a name="line-53"></a> <span class='hs-conid'>Or</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
63+<a name="line-54"></a> <span class='hs-conid'>Or</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
64+<a name="line-55"></a> <span class='hs-conid'>Or</span> <span class='hs-varid'>a</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
65+<a name="line-56"></a>
66+<a name="line-57"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>And</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>where</span>
67+<a name="line-58"></a> <span class='hs-conid'>And</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
68+<a name="line-59"></a> <span class='hs-conid'>And</span> <span class='hs-varid'>a</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
69+<a name="line-60"></a> <span class='hs-conid'>And</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
70+<a name="line-61"></a>
71+<a name="line-62"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>a</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
72+<a name="line-63"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-layout'>(</span><span class='hs-varid'>sa</span> <span class='hs-conop'>:&lt;|&gt;</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Or</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span>
73+<a name="line-64"></a> <span class='hs-conid'>IsElem</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
74+<a name="line-65"></a> <span class='hs-conid'>IsElem</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sa</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>Capture</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
75+<a name="line-66"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-layout'>(</span><span class='hs-conid'>ReqBody</span> <span class='hs-varid'>x</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
76+<a name="line-67"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-layout'>(</span><span class='hs-conid'>QueryParam</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>sb</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>sa</span> <span class='hs-varid'>sb</span>
77+<a name="line-68"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
78+<a name="line-69"></a> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>e</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
79+<a name="line-70"></a>
80+<a name="line-71"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink''</span> <span class='hs-varid'>l</span> <span class='hs-keyword'>where</span>
81+<a name="line-72"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-conid'>Get</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
82+<a name="line-73"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-conid'>Post</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
83+<a name="line-74"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-conid'>Put</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
84+<a name="line-75"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span> <span class='hs-conop'>:&gt;</span> <span class='hs-conid'>Delete</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span>
85+<a name="line-76"></a> <span class='hs-conid'>IsLink''</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>False</span>
86+<a name="line-77"></a>
87+<a name="line-78"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink'</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>where</span>
88+<a name="line-79"></a> <span class='hs-conid'>IsLink'</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Symbol</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
89+<a name="line-80"></a>
90+<a name="line-81"></a><span class='hs-keyword'>type</span> <span class='hs-varid'>family</span> <span class='hs-conid'>IsLink</span> <span class='hs-varid'>e</span> <span class='hs-keyword'>where</span>
91+<a name="line-82"></a> <span class='hs-conid'>IsLink</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Or</span> <span class='hs-layout'>(</span><span class='hs-conid'>And</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink'</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink''</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
92+<a name="line-83"></a> <span class='hs-layout'>(</span><span class='hs-conid'>IsLink''</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
93+<a name="line-84"></a>
94+<a name="line-85"></a>
95+<a name="line-86"></a><a name="ValidLinkIn"></a><span class='hs-comment'>-- | The 'ValidLinkIn f s' constraint holds when 's' is an API that</span>
96+<a name="line-87"></a><a name="ValidLinkIn"></a><span class='hs-comment'>-- contains 'f', and 'f' is a link.</span>
97+<a name="line-88"></a><a name="ValidLinkIn"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>ValidLinkIn</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
98+<a name="line-89"></a> <span class='hs-varid'>mkLink</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Link</span> <span class='hs-comment'>-- ^ This function will only typecheck if `f`</span>
99+<a name="line-90"></a> <span class='hs-comment'>-- is an URI within `s`</span>
100+<a name="line-91"></a>
101+<a name="line-92"></a><a name="instance%20ValidLinkIn%20f%20s"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span> <span class='hs-conid'>IsElem</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>~</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
102+<a name="line-93"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>IsLink</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>~</span> <span class='hs-chr'>'</span><span class='hs-conid'>True</span>
103+<a name="line-94"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>ValidLinkIn</span> <span class='hs-varid'>f</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>where</span>
104+<a name="line-95"></a> <span class='hs-varid'>mkLink</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Link</span> <span class='hs-layout'>(</span><span class='hs-varid'>vlh</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
105+<a name="line-96"></a>
106+<a name="line-97"></a><a name="Link"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Link</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Link</span> <span class='hs-conid'>String</span> <span class='hs-keyword'>deriving</span> <span class='hs-conid'>Show</span>
107+<a name="line-98"></a>
108+<a name="line-99"></a><a name="VLinkHelper"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>f</span> <span class='hs-keyword'>where</span>
109+<a name="line-100"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyword'>forall</span> <span class='hs-varid'>proxy</span><span class='hs-varop'>.</span> <span class='hs-varid'>proxy</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
110+<a name="line-101"></a>
111+<a name="line-102"></a><a name="instance%20VLinkHelper%20(s%20:%3e%20e)"></a><span class='hs-keyword'>instance</span> <span class='hs-layout'>(</span><span class='hs-conid'>KnownSymbol</span> <span class='hs-varid'>s</span><span class='hs-layout'>,</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=&gt;</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-conop'>:&gt;</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
112+<a name="line-103"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"/"</span> <span class='hs-varop'>++</span> <span class='hs-varid'>symbolVal</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varop'>++</span> <span class='hs-varid'>vlh</span> <span class='hs-layout'>(</span><span class='hs-conid'>Proxy</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Proxy</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span>
113+<a name="line-104"></a>
114+<a name="line-105"></a><a name="instance%20VLinkHelper%20(Get%20x)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-conid'>Get</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
115+<a name="line-106"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
116+<a name="line-107"></a>
117+<a name="line-108"></a><a name="instance%20VLinkHelper%20(Post%20x)"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>VLinkHelper</span> <span class='hs-layout'>(</span><span class='hs-conid'>Post</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
118+<a name="line-109"></a> <span class='hs-varid'>vlh</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
119+<a name="line-110"></a>
120+</pre></body>
121+</html>
src/Servant-Utils-StaticFiles.htmlnew file+47
@@ -0,0 +1,47 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant/Utils/StaticFiles.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-comment'>-- | This module defines a sever-side handler that lets you serve static files.</span>
11+<a name="line-2"></a><span class='hs-comment'>--</span>
12+<a name="line-3"></a><span class='hs-comment'>-- - 'serveDirectory' lets you serve anything that lives under a particular</span>
13+<a name="line-4"></a><span class='hs-comment'>-- directory on your filesystem.</span>
14+<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span> <span class='hs-layout'>(</span>
15+<a name="line-6"></a> <span class='hs-varid'>serveDirectory</span><span class='hs-layout'>,</span>
16+<a name="line-7"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
17+<a name="line-8"></a>
18+<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Filesystem</span><span class='hs-varop'>.</span><span class='hs-conid'>Path</span><span class='hs-varop'>.</span><span class='hs-conid'>CurrentOS</span> <span class='hs-layout'>(</span><span class='hs-varid'>decodeString</span><span class='hs-layout'>)</span>
19+<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Network</span><span class='hs-varop'>.</span><span class='hs-conid'>Wai</span><span class='hs-varop'>.</span><span class='hs-conid'>Application</span><span class='hs-varop'>.</span><span class='hs-conid'>Static</span>
20+<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-varop'>.</span><span class='hs-conid'>Raw</span>
21+<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
22+<a name="line-13"></a>
23+<a name="line-14"></a><a name="serveDirectory"></a><span class='hs-comment'>-- | Serve anything under the specified directory as a 'Raw' endpoint.</span>
24+<a name="line-15"></a><span class='hs-comment'>--</span>
25+<a name="line-16"></a><span class='hs-comment'>-- @</span>
26+<a name="line-17"></a><span class='hs-comment'>-- type MyApi = "static" :&gt; Raw</span>
27+<a name="line-18"></a><span class='hs-comment'>--</span>
28+<a name="line-19"></a><span class='hs-comment'>-- server :: Server MyApi</span>
29+<a name="line-20"></a><span class='hs-comment'>-- server = serveDirectory "\/var\/www"</span>
30+<a name="line-21"></a><span class='hs-comment'>-- @</span>
31+<a name="line-22"></a><span class='hs-comment'>--</span>
32+<a name="line-23"></a><span class='hs-comment'>-- would capture any request to @\/static\/\&lt;something&gt;@ and look for</span>
33+<a name="line-24"></a><span class='hs-comment'>-- @\&lt;something&gt;@ under @\/var\/www@.</span>
34+<a name="line-25"></a><span class='hs-comment'>--</span>
35+<a name="line-26"></a><span class='hs-comment'>-- It will do its best to guess the MIME type for that file, based on the extension,</span>
36+<a name="line-27"></a><span class='hs-comment'>-- and send an appropriate /Content-Type/ header if possible.</span>
37+<a name="line-28"></a><span class='hs-comment'>--</span>
38+<a name="line-29"></a><span class='hs-comment'>-- If your goal is to serve HTML, CSS and Javascript files that use the rest of the API</span>
39+<a name="line-30"></a><span class='hs-comment'>-- as a webapp backend, you will most likely not want the static files to be hidden</span>
40+<a name="line-31"></a><span class='hs-comment'>-- behind a /\/static\// prefix. In that case, remember to put the 'serveDirectory'</span>
41+<a name="line-32"></a><span class='hs-comment'>-- handler in the last position, because /servant/ will try to match the handlers</span>
42+<a name="line-33"></a><span class='hs-comment'>-- in order.</span>
43+<a name="line-34"></a><span class='hs-definition'>serveDirectory</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FilePath</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Server</span> <span class='hs-conid'>Raw</span>
44+<a name="line-35"></a><span class='hs-definition'>serveDirectory</span> <span class='hs-varid'>documentRoot</span> <span class='hs-keyglyph'>=</span>
45+<a name="line-36"></a> <span class='hs-varid'>staticApp</span> <span class='hs-layout'>(</span><span class='hs-varid'>defaultFileServerSettings</span> <span class='hs-layout'>(</span><span class='hs-varid'>decodeString</span> <span class='hs-layout'>(</span><span class='hs-varid'>documentRoot</span> <span class='hs-varop'>++</span> <span class='hs-str'>"/"</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
46+</pre></body>
47+</html>
src/Servant.htmlnew file+35
@@ -0,0 +1,35 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3+<html>
4+<head>
5+<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
6+<title>src/Servant.hs</title>
7+<link type='text/css' rel='stylesheet' href='hscolour.css' />
8+</head>
9+<body>
10+<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span> <span class='hs-layout'>(</span>
11+<a name="line-2"></a> <span class='hs-comment'>-- | This module and its submodules can be used to define servant APIs. Note</span>
12+<a name="line-3"></a> <span class='hs-comment'>-- that these API definitions don't directly implement a server (or anything</span>
13+<a name="line-4"></a> <span class='hs-comment'>-- else).</span>
14+<a name="line-5"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span><span class='hs-layout'>,</span>
15+<a name="line-6"></a> <span class='hs-comment'>-- | For implementing servers for servant APIs.</span>
16+<a name="line-7"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span><span class='hs-layout'>,</span>
17+<a name="line-8"></a> <span class='hs-comment'>-- | Using your types in request paths and query string parameters</span>
18+<a name="line-9"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span><span class='hs-layout'>,</span>
19+<a name="line-10"></a> <span class='hs-comment'>-- | Utilities on top of the servant core</span>
20+<a name="line-11"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span><span class='hs-layout'>,</span>
21+<a name="line-12"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span><span class='hs-layout'>,</span>
22+<a name="line-13"></a> <span class='hs-keyword'>module</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span><span class='hs-layout'>,</span>
23+<a name="line-14"></a> <span class='hs-comment'>-- | Useful re-exports</span>
24+<a name="line-15"></a> <span class='hs-conid'>Proxy</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
25+<a name="line-16"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
26+<a name="line-17"></a>
27+<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Proxy</span>
28+<a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>API</span>
29+<a name="line-20"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Common</span><span class='hs-varop'>.</span><span class='hs-conid'>Text</span>
30+<a name="line-21"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Server</span>
31+<a name="line-22"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>QQ</span>
32+<a name="line-23"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>Links</span>
33+<a name="line-24"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Servant</span><span class='hs-varop'>.</span><span class='hs-conid'>Utils</span><span class='hs-varop'>.</span><span class='hs-conid'>StaticFiles</span>
34+</pre></body>
35+</html>
src/hscolour.cssnew file+5
@@ -0,0 +1,5 @@
1+.hs-keyglyph, .hs-layout {color: red;}
2+.hs-keyword {color: blue;}
3+.hs-comment, .hs-comment a {color: green;}
4+.hs-str, .hs-chr {color: teal;}
5+.hs-keyword, .hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {}
synopsis.pngnew file

Binary file not shown.