git.iko.soy/typeable/swagger2
on master help sign in
Add Haddock documentation for Data.Swagger.Schema
commite35f806688ffa0568a7fa8133563d0d0d6b76454 authorNickolay Kudasov <nickolay.kudasov@gmail.com> dateWed 25 Nov 2015, 15:50 (11 years ago) parent01e66d8
2 files changed+103−5
src/Data/Swagger/Schema.hs+14−4 src/Data/Swagger/Schema/Internal.hs+89−1
src/Data/Swagger/Schema.hs+14−4
@@ -1,18 +1,28 @@
1+-- |
2+-- Module: Data.Swagger.Schema
3+-- Copyright: (c) 2015 GetShopTV
4+-- License: BSD3
5+-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
6+-- Stability: experimental
7+--
8+-- Types and functions for working with Swagger schema.
19module Data.Swagger.Schema (
10+ -- * Encoding
211 ToSchema(..),
312 NamedSchema,
413 toSchema,
514 toSchemaRef,
615 schemaName,
716
8− SchemaOptions(..),
9− defaultSchemaOptions,
10−
17+ -- * Generic schema encoding
1118 genericToSchema,
1219 genericToNamedSchema,
1320 genericToNamedSchemaBoundedIntegral,
14−
1521 toSchemaBoundedIntegral,
22+
23+ -- * Generic encoding configuration
24+ SchemaOptions(..),
25+ defaultSchemaOptions,
1626) where
1727
1828import Data.Swagger.Schema.Internal
src/Data/Swagger/Schema/Internal.hs+89−1
@@ -29,6 +29,8 @@ import GHC.Generics
2929import Data.Swagger.Internal
3030import Data.Swagger.Lens
3131
32+-- | A @'Schema'@ with an optional name.
33+-- This name can be used in references.
3234type NamedSchema = (Maybe String, Schema)
3335
3436unnamed :: Schema -> NamedSchema
@@ -37,17 +39,62 @@ unnamed schema = (Nothing, schema)
3739named :: String -> Schema -> NamedSchema
3840named name schema = (Just name, schema)
3941
42+-- | Convert a type into @'Schema'@.
43+--
44+-- An example type and instance:
45+--
46+-- @
47+-- {-\# LANGUAGE OverloadedStrings \#-} -- allows to write 'T.Text' literals
48+-- {-\# LANGUAGE OverloadedLists \#-} -- allows to write 'Map' as list
49+--
50+-- import Control.Lens
51+--
52+-- data Coord = Coord { x :: Double, y :: Double }
53+--
54+-- instance ToSchema Coord where
55+-- toNamedSchema = (Just \"Coord\", mempty
56+-- & schemaType .~ SchemaObject
57+-- & schemaProperties .~
58+-- [ ("x", toSchemaRef (Proxy :: Proxy Double))
59+-- , ("y", toSchemaRef (Proxy :: Proxy Double))
60+-- ]
61+-- & schemaRequired .~ [ "x", "y" ]
62+-- @
63+--
64+-- Instead of manually writing your @'ToSchema'@ instance you can
65+-- use a default generic implementation of @'toNamedSchema'@.
66+--
67+-- To do that, simply add @deriving 'Generic'@ clause to your datatype
68+-- and declare a @'ToSchema'@ instance for your datatype without
69+-- giving definition for @'toNamedSchema'@.
70+--
71+-- For instance, the previous example can be simplified into this:
72+--
73+-- @
74+-- {-\# LANGUAGE DeriveGeneric \#-}
75+--
76+-- import GHC.Generics (Generic)
77+--
78+-- data Coord = Coord { x :: Double, y :: Double } deriving Generic
79+--
80+-- instance ToSchema Coord
81+-- @
4082class ToSchema a where
83+ -- | Convert a type into an optionally named schema.
4184 toNamedSchema :: proxy a -> NamedSchema
4285 default toNamedSchema :: (Generic a, GToSchema (Rep a)) => proxy a -> NamedSchema
4386 toNamedSchema = genericToNamedSchema defaultSchemaOptions
4487
88+-- | Get type's schema name according to its @'ToSchema'@ instance.
4589schemaName :: ToSchema a => proxy a -> Maybe String
4690schemaName = fst . toNamedSchema
4791
92+-- | Convert a type into a schema.
4893toSchema :: ToSchema a => proxy a -> Schema
4994toSchema = snd . toNamedSchema
5095
96+-- | Convert a type into a referenced schema if possible.
97+-- Only named schemas can be references, nameless schemas are inlined.
5198toSchemaRef :: ToSchema a => proxy a -> Referenced Schema
5299toSchemaRef proxy = case toNamedSchema proxy of
53100 (Just name, _) -> Ref (Reference ("#/definitions/" <> T.pack name))
@@ -134,15 +181,49 @@ instance ToSchema a => ToSchema (First a) where toNamedSchema _ = unnamed $ to
134181instance ToSchema a => ToSchema (Last a) where toNamedSchema _ = unnamed $ toSchema (Proxy :: Proxy a)
135182instance ToSchema a => ToSchema (Dual a) where toNamedSchema _ = unnamed $ toSchema (Proxy :: Proxy a)
136183
184+-- | Options that specify how to encode your type to Swagger schema.
137185data SchemaOptions = SchemaOptions
138− { fieldLabelModifier :: String -> String
186+ { -- | Function applied to field labels. Handy for removing common record prefixes for example.
187+ fieldLabelModifier :: String -> String
188+ -- | Function applied to constructor tags which could be handy for lower-casing them for example.
139189 , constructorTagModifier :: String -> String
190+ -- | Function applied to datatype name.
140191 , datatypeNameModifier :: String -> String
192+ -- | If @'True'@ the constructors of a datatype, with all nullary constructors,
193+ -- will be encoded to a string enumeration schema with the constructor tags as possible values.
141194 , allNullaryToStringTag :: Bool
195+ -- | If @'True'@ direct subschemas will be referenced if possible (rather than inlined).
196+ -- Note that this option does not influence nested schemas, e.g. for these types
197+ --
198+ -- @
199+ -- data Object = Object String deriving Generic
200+ -- instance ToSchema Object
201+ --
202+ -- newtype Objects = Objects [Object] deriving Generic
203+ -- instance ToSchema Objects where
204+ -- toNamedSchema = genericToNamedSchema defaultSchemaOptions
205+ -- { useReferences = False }
206+ -- @
207+ --
208+ -- Schema for @Objects@ __will not__ inline @Object@ schema because
209+ -- it is nested in a @[]@ schema.
142210 , useReferences :: Bool
211+ -- | Hide the field name when a record constructor has only one field, like a newtype.
143212 , unwrapUnaryRecords :: Bool
144213 }
145214
215+-- | Default encoding @'SchemaOptions'@.
216+--
217+-- @
218+-- 'SchemaOptions'
219+-- { 'fieldLabelModifier' = id
220+-- , 'constructorTagModifier' = id
221+-- , 'datatypeNameModifier' = id
222+-- , 'allNullaryToStringTag' = True
223+-- , 'useReferences' = True
224+-- , 'unwrapUnaryRecords' = False
225+-- }
226+-- @
146227defaultSchemaOptions :: SchemaOptions
147228defaultSchemaOptions = SchemaOptions
148229 { fieldLabelModifier = id
@@ -153,12 +234,14 @@ defaultSchemaOptions = SchemaOptions
153234 , unwrapUnaryRecords = False
154235 }
155236
237+-- | Default schema for @'Bounded'@, @'Integral'@ types.
156238toSchemaBoundedIntegral :: forall a proxy. (Bounded a, Integral a) => proxy a -> Schema
157239toSchemaBoundedIntegral _ = mempty
158240 & schemaType .~ SchemaInteger
159241 & schemaMinimum ?~ fromInteger (toInteger (minBound :: a))
160242 & schemaMaximum ?~ fromInteger (toInteger (maxBound :: a))
161243
244+-- | Default generic named schema for @'Bounded'@, @'Integral'@ types.
162245genericToNamedSchemaBoundedIntegral :: forall a d f proxy.
163246 ( Bounded a, Integral a
164247 , Generic a, Rep a ~ D1 d f, Datatype d)
@@ -166,9 +249,14 @@ genericToNamedSchemaBoundedIntegral :: forall a d f proxy.
166249genericToNamedSchemaBoundedIntegral opts proxy
167250 = (gdatatypeSchemaName opts (Proxy :: Proxy d), toSchemaBoundedIntegral proxy)
168251
252+-- | A configurable generic @'Schema'@ creator.
169253genericToSchema :: (Generic a, GToSchema (Rep a)) => SchemaOptions -> proxy a -> Schema
170254genericToSchema opts = snd . genericToNamedSchema opts
171255
256+-- | A configurable generic @'NamedSchema'@ creator.
257+-- This function applied to @'defaultSchemaOptions'@
258+-- is used as the default for @'toNamedSchema'@
259+-- when the type is an instance of @'Generic'@.
172260genericToNamedSchema :: forall a proxy. (Generic a, GToSchema (Rep a)) => SchemaOptions -> proxy a -> NamedSchema
173261genericToNamedSchema opts _ = gtoNamedSchema opts (Proxy :: Proxy (Rep a)) mempty
174262