on master help sign in
Add DocOptions with maxSamples field

With DocOptions one can limit maximum number of samples. This is useful for Generic-based instances for recursive data types (e.g. `[]`). Default options set maxSamples to 5.

commit42f5795fccfa90b1105797e4c00647ecb797a63a authorNickolay Kudasov <nickolay.kudasov@gmail.com> dateMon 21 Sep 2015, 13:36 (11 years ago) parentf96915e
4 files changed+49−28
servant-docs/example/greet.hs+1−1 servant-docs/src/Servant/Docs.hs+3−1 servant-docs/src/Servant/Docs/Internal.hs+44−25 servant-docs/test/Servant/DocsSpec.hs+1−1
servant-docs/example/greet.hs+1−1
@@ -112,7 +112,7 @@ extra =
112112--
113113-- > docs testAPI :: API
114114docsGreet :: API
115−docsGreet = docsWith [intro1, intro2] extra testApi
115+docsGreet = docsWith defaultDocOptions [intro1, intro2] extra testApi
116116
117117main :: IO ()
118118main = putStrLn $ markdown docsGreet
servant-docs/src/Servant/Docs.hs+3−1
@@ -144,7 +144,9 @@ module Servant.Docs
144144 ( -- * 'HasDocs' class and key functions
145145 HasDocs(..), docs, markdown
146146 -- * Generating docs with extra information
147− , ExtraInfo(..), docsWith, docsWithIntros, extraInfo
147+ , docsWith, docsWithIntros, docsWithOptions
148+ , ExtraInfo(..), extraInfo
149+ , DocOptions(..) , defaultDocOptions, maxSamples
148150
149151 , -- * Classes you need to implement for your types
150152 ToSample(..)
servant-docs/src/Servant/Docs/Internal.hs+44−25
@@ -9,6 +9,7 @@
99{-# LANGUAGE MultiParamTypeClasses #-}
1010{-# LANGUAGE OverloadedStrings #-}
1111{-# LANGUAGE PolyKinds #-}
12+{-# LANGUAGE RecordWildCards #-}
1213{-# LANGUAGE ScopedTypeVariables #-}
1314{-# LANGUAGE TemplateHaskell #-}
1415{-# LANGUAGE TupleSections #-}
@@ -176,6 +177,16 @@ instance Monoid (ExtraInfo a) where
176177 ExtraInfo a `mappend` ExtraInfo b =
177178 ExtraInfo $ HM.unionWith combineAction a b
178179
180+-- | Documentation options.
181+data DocOptions = DocOptions
182+ { _maxSamples :: Int -- ^ Maximum samples allowed.
183+ } deriving (Show)
184+
185+-- | Default documentation options.
186+defaultDocOptions :: DocOptions
187+defaultDocOptions = DocOptions
188+ { _maxSamples = 5 }
189+
179190-- | Type of GET parameter:
180191--
181192-- - Normal corresponds to @QueryParam@, i.e your usual GET parameter
@@ -280,6 +291,7 @@ single :: Endpoint -> Action -> API
280291single e a = API mempty (HM.singleton e a)
281292
282293-- gimme some lenses
294+makeLenses ''DocOptions
283295makeLenses ''API
284296makeLenses ''Endpoint
285297makeLenses ''DocCapture
@@ -291,8 +303,14 @@ makeLenses ''Action
291303
292304-- | Generate the docs for a given API that implements 'HasDocs'. This is the
293305-- default way to create documentation.
306+--
307+-- prop> docs == docsWithOptions defaultDocOptions
294308docs :: HasDocs layout => Proxy layout -> API
295−docs p = docsFor p (defEndpoint, defAction)
309+docs p = docsWithOptions p defaultDocOptions
310+
311+-- | Generate the docs for a given API that implements 'HasDocs'.
312+docsWithOptions :: HasDocs layout => Proxy layout -> DocOptions -> API
313+docsWithOptions p = docsFor p (defEndpoint, defAction)
296314
297315-- | Closed type family, check if endpoint is exactly within API.
298316
@@ -319,7 +337,7 @@ type family IsIn (endpoint :: *) (api :: *) :: Constraint where
319337extraInfo :: (IsIn endpoint layout, HasLink endpoint, HasDocs endpoint)
320338 => Proxy endpoint -> Action -> ExtraInfo layout
321339extraInfo p action =
322− let api = docsFor p (defEndpoint, defAction)
340+ let api = docsFor p (defEndpoint, defAction) defaultDocOptions
323341 -- Assume one endpoint, HasLink constraint means that we should only ever
324342 -- point at one endpoint.
325343 in ExtraInfo $ api ^. apiEndpoints & traversed .~ action
@@ -336,21 +354,22 @@ extraInfo p action =
336354-- 'extraInfo'.
337355--
338356-- If you only want to add an introduction, use 'docsWithIntros'.
339−docsWith :: HasDocs layout => [DocIntro] -> ExtraInfo layout -> Proxy layout -> API
340−docsWith intros (ExtraInfo endpoints) p =
341− docs p & apiIntros <>~ intros
342− & apiEndpoints %~ HM.unionWith (flip combineAction) endpoints
357+docsWith :: HasDocs layout => DocOptions -> [DocIntro] -> ExtraInfo layout -> Proxy layout -> API
358+docsWith opts intros (ExtraInfo endpoints) p =
359+ docsWithOptions p opts
360+ & apiIntros <>~ intros
361+ & apiEndpoints %~ HM.unionWith (flip combineAction) endpoints
343362
344363
345364-- | Generate the docs for a given API that implements 'HasDocs' with with any
346365-- number of introduction(s)
347366docsWithIntros :: HasDocs layout => [DocIntro] -> Proxy layout -> API
348−docsWithIntros intros = docsWith intros mempty
367+docsWithIntros intros = docsWith defaultDocOptions intros mempty
349368
350369-- | The class that abstracts away the impact of API combinators
351370-- on documentation generation.
352371class HasDocs layout where
353− docsFor :: Proxy layout -> (Endpoint, Action) -> API
372+ docsFor :: Proxy layout -> (Endpoint, Action) -> DocOptions -> API
354373
355374-- | The class that lets us display a sample input or output in the supported
356375-- content-types when generating documentation for endpoints that either:
@@ -709,11 +728,11 @@ instance
709728#endif
710729 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts)
711730 => HasDocs (Delete cts a) where
712− docsFor Proxy (endpoint, action) =
731+ docsFor Proxy (endpoint, action) DocOptions{..} =
713732 single endpoint' action'
714733
715734 where endpoint' = endpoint & method .~ DocDELETE
716− action' = action & response.respBody .~ sampleByteStrings t p
735+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
717736 & response.respTypes .~ supportedTypes t
718737 t = Proxy :: Proxy cts
719738 p = Proxy :: Proxy a
@@ -725,12 +744,12 @@ instance
725744 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts
726745 , AllHeaderSamples ls , GetHeaders (HList ls) )
727746 => HasDocs (Delete cts (Headers ls a)) where
728− docsFor Proxy (endpoint, action) =
747+ docsFor Proxy (endpoint, action) DocOptions{..} =
729748 single endpoint' action'
730749
731750 where hdrs = allHeaderToSample (Proxy :: Proxy ls)
732751 endpoint' = endpoint & method .~ DocDELETE
733− action' = action & response.respBody .~ sampleByteStrings t p
752+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
734753 & response.respTypes .~ supportedTypes t
735754 & response.respHeaders .~ hdrs
736755 t = Proxy :: Proxy cts
@@ -742,11 +761,11 @@ instance
742761#endif
743762 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts)
744763 => HasDocs (Get cts a) where
745− docsFor Proxy (endpoint, action) =
764+ docsFor Proxy (endpoint, action) DocOptions{..} =
746765 single endpoint' action'
747766
748767 where endpoint' = endpoint & method .~ DocGET
749− action' = action & response.respBody .~ sampleByteStrings t p
768+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
750769 & response.respTypes .~ supportedTypes t
751770 t = Proxy :: Proxy cts
752771 p = Proxy :: Proxy a
@@ -758,12 +777,12 @@ instance
758777 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts
759778 , AllHeaderSamples ls , GetHeaders (HList ls) )
760779 => HasDocs (Get cts (Headers ls a)) where
761− docsFor Proxy (endpoint, action) =
780+ docsFor Proxy (endpoint, action) DocOptions{..} =
762781 single endpoint' action'
763782
764783 where hdrs = allHeaderToSample (Proxy :: Proxy ls)
765784 endpoint' = endpoint & method .~ DocGET
766− action' = action & response.respBody .~ sampleByteStrings t p
785+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
767786 & response.respTypes .~ supportedTypes t
768787 & response.respHeaders .~ hdrs
769788 t = Proxy :: Proxy cts
@@ -784,11 +803,11 @@ instance
784803#endif
785804 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts)
786805 => HasDocs (Post cts a) where
787− docsFor Proxy (endpoint, action) =
806+ docsFor Proxy (endpoint, action) DocOptions{..} =
788807 single endpoint' action'
789808
790809 where endpoint' = endpoint & method .~ DocPOST
791− action' = action & response.respBody .~ sampleByteStrings t p
810+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
792811 & response.respTypes .~ supportedTypes t
793812 & response.respStatus .~ 201
794813 t = Proxy :: Proxy cts
@@ -801,12 +820,12 @@ instance
801820 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts
802821 , AllHeaderSamples ls , GetHeaders (HList ls) )
803822 => HasDocs (Post cts (Headers ls a)) where
804− docsFor Proxy (endpoint, action) =
823+ docsFor Proxy (endpoint, action) DocOptions{..} =
805824 single endpoint' action'
806825
807826 where hdrs = allHeaderToSample (Proxy :: Proxy ls)
808827 endpoint' = endpoint & method .~ DocPOST
809− action' = action & response.respBody .~ sampleByteStrings t p
828+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
810829 & response.respTypes .~ supportedTypes t
811830 & response.respStatus .~ 201
812831 & response.respHeaders .~ hdrs
@@ -819,11 +838,11 @@ instance
819838#endif
820839 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts)
821840 => HasDocs (Put cts a) where
822− docsFor Proxy (endpoint, action) =
841+ docsFor Proxy (endpoint, action) DocOptions{..} =
823842 single endpoint' action'
824843
825844 where endpoint' = endpoint & method .~ DocPUT
826− action' = action & response.respBody .~ sampleByteStrings t p
845+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
827846 & response.respTypes .~ supportedTypes t
828847 & response.respStatus .~ 200
829848 t = Proxy :: Proxy cts
@@ -836,12 +855,12 @@ instance
836855 (ToSample a b, IsNonEmpty cts, AllMimeRender cts b, SupportedTypes cts
837856 , AllHeaderSamples ls , GetHeaders (HList ls) )
838857 => HasDocs (Put cts (Headers ls a)) where
839− docsFor Proxy (endpoint, action) =
858+ docsFor Proxy (endpoint, action) DocOptions{..} =
840859 single endpoint' action'
841860
842861 where hdrs = allHeaderToSample (Proxy :: Proxy ls)
843862 endpoint' = endpoint & method .~ DocPUT
844− action' = action & response.respBody .~ sampleByteStrings t p
863+ action' = action & response.respBody .~ take _maxSamples (sampleByteStrings t p)
845864 & response.respTypes .~ supportedTypes t
846865 & response.respStatus .~ 200
847866 & response.respHeaders .~ hdrs
@@ -923,7 +942,7 @@ instance (KnownSymbol sym, {- ToParam (MatrixFlag sym), -} HasDocs sublayout)
923942 symP = Proxy :: Proxy sym
924943
925944instance HasDocs Raw where
926− docsFor _proxy (endpoint, action) =
945+ docsFor _proxy (endpoint, action) _ =
927946 single endpoint action
928947
929948-- TODO: We use 'AllMimeRender' here because we need to be able to show the
servant-docs/test/Servant/DocsSpec.hs+1−1
@@ -36,7 +36,7 @@ spec = describe "Servant.Docs" $ do
3636 extraInfo
3737 (Proxy :: Proxy (ReqBody '[JSON] String :> Post '[JSON] Datatype1))
3838 (defAction & notes <>~ [DocNote "Post data" ["Posts some Json data"]])
39− md = markdown (docsWith [] extra (Proxy :: Proxy TestApi1))
39+ md = markdown (docsWith defaultDocOptions [] extra (Proxy :: Proxy TestApi1))
4040 tests md
4141 it "contains the extra info provided" $ do
4242 md `shouldContain` "Get an Integer"