-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | generate API docs for your servant webservice -- -- Library for generating API docs from a servant API definition. -- -- Runnable example here. @package servant-docs @version 0.3 -- | This module lets you get API docs for free. It lets generate an -- API from the type that represents your API using docs: -- --
--   docs :: HasDocs api => Proxy api -> API
--   
-- -- You can then call markdown on it: -- --
--   markdown :: API -> String
--   
-- -- or define a custom pretty printer: -- --
--   yourPrettyDocs :: API -> String -- or blaze-html's HTML, or ...
--   
-- -- The only thing you'll need to do will be to implement some classes for -- your captures, get parameters and request or response bodies. -- -- Here's a little (but complete) example that you can run to see the -- markdown pretty printer in action: -- --
--   {-# LANGUAGE DataKinds #-}
--   {-# LANGUAGE PolyKinds #-}
--   {-# LANGUAGE TypeFamilies #-}
--   {-# LANGUAGE DeriveGeneric #-}
--   {-# LANGUAGE TypeOperators #-}
--   {-# LANGUAGE FlexibleInstances #-}
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Data.Proxy
--   import Data.Text
--   import Servant
--   
--   -- our type for a Greeting message
--   data Greet = Greet { _msg :: Text }
--     deriving (Generic, Show)
--   
--   -- we get our JSON serialization for free
--   instance FromJSON Greet
--   instance ToJSON Greet
--   
--   -- we provide a sample value for the 'Greet' type
--   instance ToSample Greet where
--     toSample = Just g
--   
--       where g = Greet "Hello, haskeller!"
--   
--   instance ToParam (QueryParam "capital" Bool) where
--     toParam _ =
--       DocQueryParam "capital"
--                     ["true", "false"]
--                     "Get the greeting message in uppercase (true) or not (false). Default is false."
--   
--   instance ToCapture (Capture "name" Text) where
--     toCapture _ = DocCapture "name" "name of the person to greet"
--   
--   instance ToCapture (Capture "greetid" Text) where
--     toCapture _ = DocCapture "greetid" "identifier of the greet msg to remove"
--   
--   -- API specification
--   type TestApi =
--          "hello" :> Capture "name" Text :> QueryParam "capital" Bool :> Get Greet
--     :<|> "greet" :> RQBody Greet :> Post Greet
--     :<|> "delete" :> Capture "greetid" Text :> Delete
--   
--   testApi :: Proxy TestApi
--   testApi = Proxy
--   
--   -- Generate the Documentation's ADT
--   greetDocs :: API
--   greetDocs = docs testApi
--   
--   main :: IO ()
--   main = putStrLn $ markdown greetDocs
--   
module Servant.Docs -- | The class that abstracts away the impact of API combinators on -- documentation generation. class HasDocs layout docsFor :: HasDocs layout => Proxy layout -> (Endpoint, Action) -> API -- | Generate the docs for a given API that implements HasDocs. docs :: HasDocs layout => Proxy layout -> API -- | Generate documentation in Markdown format for the given API. markdown :: API -> String -- | The class that lets us display a sample JSON input or output when -- generating documentation for endpoints that either: -- -- -- -- Example of an instance: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Data.Aeson
--   import Data.Text
--   import GHC.Generics
--   
--   data Greet = Greet { _msg :: Text }
--     deriving (Generic, Show)
--   
--   instance FromJSON Greet
--   instance ToJSON Greet
--   
--   instance ToSample Greet where
--     toSample = Just g
--   
--       where g = Greet "Hello, haskeller!"
--   
-- -- You can also instantiate this class using toSamples instead of -- toSample: it lets you specify different responses along with -- some context (as Text) that explains when you're supposed to -- get the corresponding response. class ToJSON a => ToSample a where toSample = fmap snd $ listToMaybe samples where samples = toSamples :: [(Text, a)] toSamples = maybe [] (return . ("",)) s where s = toSample :: Maybe a toSample :: ToSample a => Maybe a toSamples :: ToSample a => [(Text, a)] sampleByteString :: ToSample a => Proxy a -> Maybe ByteString sampleByteStrings :: ToSample a => Proxy a -> [(Text, ByteString)] -- | The class that helps us automatically get documentation for GET -- parameters. -- -- Example of an instance: -- --
--   instance ToParam (QueryParam "capital" Bool) where
--     toParam _ =
--       DocQueryParam "capital"
--                     ["true", "false"]
--                     "Get the greeting message in uppercase (true) or not (false). Default is false."
--   
class ToParam t toParam :: ToParam t => Proxy t -> DocQueryParam -- | The class that helps us automatically get documentation for URL -- captures. -- -- Example of an instance: -- --
--   instance ToCapture (Capture "name" Text) where
--     toCapture _ = DocCapture "name" "name of the person to greet"
--   
class ToCapture c toCapture :: ToCapture c => Proxy c -> DocCapture -- | Supported HTTP request methods data Method -- | the DELETE method DocDELETE :: Method -- | the GET method DocGET :: Method -- | the POST method DocPOST :: Method -- | the PUT method DocPUT :: Method -- | An Endpoint type that holds the path and the -- method. -- -- Gets used as the key in the API hashmap. Modify -- defEndpoint or any Endpoint value you want using the -- path and method lenses to tweak. -- --
--   λ> defEndpoint
--   GET /
--   λ> defEndpoint & path <>~ ["foo"]
--   GET /foo
--   λ> defEndpoint & path <>~ ["foo"] & method .~ DocPOST
--   POST /foo
--   
data Endpoint path :: Lens' Endpoint [String] method :: Lens' Endpoint Method -- | An Endpoint whose path is `"/"` and whose method is -- DocGET -- -- Here's how you can modify it: -- --
--   λ> defEndpoint
--   GET /
--   λ> defEndpoint & path <>~ ["foo"]
--   GET /foo
--   λ> defEndpoint & path <>~ ["foo"] & method .~ DocPOST
--   POST /foo
--   
defEndpoint :: Endpoint -- | Our API type, a good old hashmap from Endpoint to Action type API = HashMap Endpoint Action -- | An empty API emptyAPI :: API -- | A type to represent captures. Holds the name of the capture and a -- description. -- -- Write a ToCapture instance for your captured types. data DocCapture DocCapture :: String -> String -> DocCapture _capSymbol :: DocCapture -> String _capDesc :: DocCapture -> String capSymbol :: Lens' DocCapture String capDesc :: Lens' DocCapture String -- | A type to represent a GET parameter from the Query String. -- Holds its name, the possible values (leave empty if there isn't a -- finite number of them), and a description of how it influences the -- output or behavior. -- -- Write a ToParam instance for your GET parameter types data DocQueryParam DocQueryParam :: String -> [String] -> String -> ParamKind -> DocQueryParam _paramName :: DocQueryParam -> String _paramValues :: DocQueryParam -> [String] _paramDesc :: DocQueryParam -> String _paramKind :: DocQueryParam -> ParamKind -- | Type of GET parameter: -- -- data ParamKind Normal :: ParamKind List :: ParamKind Flag :: ParamKind paramName :: Lens' DocQueryParam String paramValues :: Lens' DocQueryParam [String] paramDesc :: Lens' DocQueryParam String paramKind :: Lens' DocQueryParam ParamKind -- | A type to represent an HTTP response. Has an Int status and a -- 'Maybe ByteString' response body. Tweak defResponse using the -- respStatus and respBody lenses if you want. -- -- If you want to respond with a non-empty response body, you'll most -- likely want to write a ToSample instance for the type that'll -- be represented as some JSON in the response. -- -- Can be tweaked with two lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respBody = []}
--   λ> defResponse & respStatus .~ 204 & respBody .~ [("If everything goes well", "{ \"status\": \"ok\" }")]
--   Response {_respStatus = 204, _respBody = [("If everything goes well", "{ \"status\": \"ok\" }")]}
--   
data Response respStatus :: Lens' Response Int respBody :: Lens' Response [(Text, ByteString)] -- | Default response: status code 200, no response body. -- -- Can be tweaked with two lenses. -- --
--   λ> defResponse
--   Response {_respStatus = 200, _respBody = Nothing}
--   λ> defResponse & respStatus .~ 204 & respBody .~ Just "[]"
--   Response {_respStatus = 204, _respBody = Just "[]"}
--   
defResponse :: Response -- | A datatype that represents everything that can happen at an endpoint, -- with its lenses: -- -- -- -- You can tweak an Action (like the default defAction) -- with these lenses to transform an action and add some information to -- it. data Action captures :: Lens' Action [DocCapture] headers :: Lens' Action [Text] params :: Lens' Action [DocQueryParam] rqbody :: Lens' Action (Maybe ByteString) response :: Lens' Action Response defAction :: Action -- | Create an API that's comprised of a single endpoint. API is a -- Monoid, so combine multiple endpoints with mappend or -- <>. single :: Endpoint -> Action -> API instance (KnownSymbol path, HasDocs sublayout) => HasDocs (path :> sublayout) instance (ToSample a, HasDocs sublayout) => HasDocs (ReqBody a :> sublayout) instance HasDocs Raw instance (KnownSymbol sym, ToParam (QueryFlag sym), HasDocs sublayout) => HasDocs (QueryFlag sym :> sublayout) instance (KnownSymbol sym, ToParam (QueryParams sym a), HasDocs sublayout) => HasDocs (QueryParams sym a :> sublayout) instance (KnownSymbol sym, ToParam (QueryParam sym a), HasDocs sublayout) => HasDocs (QueryParam sym a :> sublayout) instance ToSample a => HasDocs (Put a) instance ToSample a => HasDocs (Post a) instance (KnownSymbol sym, HasDocs sublayout) => HasDocs (Header sym a :> sublayout) instance ToSample a => HasDocs (Get a) instance HasDocs Delete instance (KnownSymbol sym, ToCapture (Capture sym a), HasDocs sublayout) => HasDocs (Capture sym a :> sublayout) instance (HasDocs layout1, HasDocs layout2) => HasDocs (layout1 :<|> layout2) instance Eq Method instance Generic Method instance Eq Endpoint instance Generic Endpoint instance Eq DocCapture instance Show DocCapture instance Eq ParamKind instance Show ParamKind instance Eq DocQueryParam instance Show DocQueryParam instance Eq Response instance Show Response instance Eq Action instance Show Action instance Datatype D1Method instance Constructor C1_0Method instance Constructor C1_1Method instance Constructor C1_2Method instance Constructor C1_3Method instance Datatype D1Endpoint instance Constructor C1_0Endpoint instance Selector S1_0_0Endpoint instance Selector S1_0_1Endpoint instance Hashable Endpoint instance Show Endpoint instance Hashable Method instance Show Method