-
Notifications
You must be signed in to change notification settings - Fork 3
/
render.hs
54 lines (42 loc) · 1.74 KB
/
render.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
-- stack runghc --package servant-docs-simple
-- You may reference Renderable instances in Servant.Docs.Simple.Render for more examples
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Data.Map.Ordered (assocs)
import Data.Text (Text)
import Servant.API ((:>), Post, ReqBody)
import Servant.Docs.Simple.Parse (parseApi)
import Servant.Docs.Simple.Render (ApiDocs (..), Details (..), Renderable (..))
-- Our API type
type API = "hello" :> "world" :> Request :> Response
type Request = ReqBody '[()] ()
type Response = Post '[()] ()
-- Intermediate documentation structure
documentTree :: ApiDocs
documentTree = parseApi @API
-- Our custom datatype which we would like to render to
newtype Documented = Documented [Endpt] deriving Show -- A list of documentation for all endpoints
-- Each endpoint consists of
-- Route: (/users/data, /<route name>, etc...)
-- Information: (headers, request, response etc..)
data Endpt = Endpt Route Information deriving Show
type Route = Text
type Information = Text
-- Allow us to render the documentTree in our custom data type
instance Renderable Documented where
render (ApiDocs endpoints) = Documented endpoints'
where endpoints' = convert <$> endpoints
convert (route, info) = Endpt route (getInfo info)
-- Just mush everything together, just a proof of concept.
-- Check out Renderable instances in Servant.Docs.Simple.Render for proper implementations
getInfo :: Details -> Text
getInfo (Detail t) = t
getInfo (Details ds) = foldMap (\(t, rest) -> t <> getInfo rest) ds
-- Rendered data structure
documented :: Documented
documented = render documentTree
-- Irrelevant, just to allow compile
main :: IO ()
main = print documented