@@ -5,7 +5,28 @@
55{-# LANGUAGE ScopedTypeVariables #-}
66{-# LANGUAGE TemplateHaskell #-}
77{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
8−module Servant.Utils.ApiQuasiQuoting where
8+-- | QuasiQuoting utilities for API types.
9+--
10+-- 'sitemap' allows you to write your type in a very natural way:
11+--
12+-- @
13+-- [sitemap|
14+-- PUT hello String -> ()
15+-- POST hello/p:Int String -> ()
16+-- GET hello/?name:String Int
17+-- |]
18+-- @
19+--
20+-- Will generate:
21+--
22+-- @
23+-- "hello" :> ReqBody String :> Put ()
24+-- :\<|> "hello" :> Capture "p" Int :> ReqBody String :> Post ()
25+-- :\<|> "hello" :> QueryParam "name" String :> Get Int
26+-- @
27+--
28+-- Note the @/@ before a @QueryParam@!
29+module Servant.QQ where
930
1031import Control.Monad (void)
1132import Control.Applicative hiding (many, (<|>), optional)
@@ -23,6 +44,11 @@ import Servant.API.ReqBody
2344import Servant.API.Sub
2445import Servant.API.Alternative
2546
47+-- | Finally-tagless encoding for our DSL.
48+-- Keeping 'repr'' and 'repr' distinct when writing functions with an
49+-- @ExpSYM@ context ensures certain invariants (for instance, that there is
50+-- only one of 'get', 'post', 'put', and 'delete' in a value), but
51+-- sometimes requires a little more work.
2652class ExpSYM repr' repr | repr -> repr', repr' -> repr where
2753 lit :: String -> repr' -> repr
2854 capture :: String -> String -> repr -> repr
@@ -148,6 +174,19 @@ parseAll = do
148174 where union :: Type -> Type -> Type
149175 union a = AppT (AppT (ConT ''(:<|>)) a)
150176
177+-- | The sitemap QuasiQuoter.
178+--
179+-- * @.../<var>:<type>/...@ becomes a capture
180+-- * @.../?<var>:<type>@ becomes a query parameter
181+-- * @<method> ... <typ>@ becomes a method returning @<typ>@
182+-- * @<method> ... <typ1> -> <typ2>@ becomes a method with request
183+-- body of @<typ1>@ and returning @<typ2>@
184+--
185+-- Comments are allowed, and have the standard Haskell format
186+--
187+-- * @--@ for inline
188+-- * @{- ... -}@ for block
189+--
151190sitemap :: QuasiQuoter
152191sitemap = QuasiQuoter { quoteExp = undefined
153192 , quotePat = undefined