@@ -21,7 +21,7 @@ import Prelude.Compat
2121
2222import Control.Lens ((&), (.~), (?~))
2323import Control.Applicative
24−import Data.Aeson
24+import Data.Aeson hiding (Encoding)
2525import qualified Data.Aeson.Types as JSON
2626import Data.Data (Data(..), Typeable, mkConstr, mkDataType, Fixity(..), Constr, DataType, constrIndex)
2727import Data.Hashable (Hashable)
@@ -186,7 +186,7 @@ data Components = Components
186186 { _componentsSchemas :: Definitions Schema
187187 , _componentsResponses :: Definitions Response
188188 , _componentsParameters :: Definitions Param
189−-- , _componentsExamples
189+ , _componentsExamples :: Definitions Example
190190 , _componentsRequestBodies :: Definitions RequestBody
191191 , _componentsHeader :: Definitions Header
192192 , _componentsSecuritySchemes :: Definitions SecurityScheme
@@ -350,11 +350,59 @@ data RequestBody = RequestBody
350350data MediaTypeObject = MediaTypeObject
351351 { _mediaTypeObjectSchema :: Maybe (Referenced Schema)
352352
353−-- TODO
354−-- , _mediaTypeExample
355−-- , _mediaTypeExamples
353+ -- | Example of the media type.
354+ -- The example object SHOULD be in the correct format as specified by the media type.
355+ , _mediaTypeObjectExample :: Maybe Value
356356
357−-- , _mediaTypeEncoding :: InsOrdHashMap Text Encoding
357+ -- | Examples of the media type.
358+ -- Each example object SHOULD match the media type and specified schema if present.
359+ , _mediaTypeObjectExamples :: InsOrdHashMap Text (Referenced Example)
360+
361+ -- | A map between a property name and its encoding information.
362+ -- The key, being the property name, MUST exist in the schema as a property.
363+ -- The encoding object SHALL only apply to 'RequestBody' objects when the media type
364+ -- is @multipart@ or @application/x-www-form-urlencoded@.
365+ , _mediaTypeObjectEncoding :: InsOrdHashMap Text Encoding
366+ } deriving (Eq, Show, Generic, Data, Typeable)
367+
368+data Encoding = Encoding
369+ { -- | The Content-Type for encoding a specific property.
370+ -- Default value depends on the property type: for @string@
371+ -- with format being @binary@ – @application/octet-stream@;
372+ -- for other primitive types – @text/plain@; for object - @application/json@;
373+ -- for array – the default is defined based on the inner type.
374+ -- The value can be a specific media type (e.g. @application/json@),
375+ -- a wildcard media type (e.g. @image/*@), or a comma-separated list of the two types.
376+ _encodingContentType :: Maybe Text
377+
378+ -- | A map allowing additional information to be provided as headers,
379+ -- for example @Content-Disposition@. @Content-Type@ is described separately
380+ -- and SHALL be ignored in this section.
381+ -- This property SHALL be ignored if the request body media type is not a @multipart@.
382+ , _encodingHeaders :: InsOrdHashMap Text (Referenced Header)
383+
384+ -- | Describes how a specific property value will be serialized depending on its type.
385+ -- See Parameter Object for details on the style property.
386+ -- The behavior follows the same values as query parameters, including default values.
387+ -- This property SHALL be ignored if the request body media type
388+ -- is not @application/x-www-form-urlencoded@.
389+ , _encodingStyle :: Maybe Text -- TODO enum
390+
391+ -- | When this is true, property values of type @array@ or @object@ generate
392+ -- separate parameters for each value of the array,
393+ -- or key-value-pair of the map.
394+ -- For other types of properties this property has no effect.
395+ -- When style is form, the default value is @true@. For all other styles,
396+ -- the default value is @false@. This property SHALL be ignored
397+ -- if the request body media type is not @application/x-www-form-urlencoded@.
398+ , _encodingExplode :: Maybe Bool
399+
400+ -- | Determines whether the parameter value SHOULD allow reserved characters,
401+ -- as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
402+ -- @:/?#[]@!$&'()*+,;=@ to be included without percent-encoding.
403+ -- The default value is @false@. This property SHALL be ignored if the request body media type
404+ -- is not @application/x-www-form-urlencoded@.
405+ , _encodingAllowReserved :: Maybe Bool
358406 } deriving (Eq, Show, Generic, Data, Typeable)
359407
360408newtype MimeList = MimeList { getMimeList :: [MediaType] }
@@ -412,6 +460,28 @@ data ParamOtherSchema = ParamOtherSchema
412460 , _paramOtherSchemaParamSchema :: ParamSchema 'SwaggerKindParamOtherSchema
413461 } deriving (Eq, Show, Generic, Typeable, Data)
414462
463+data Example = Example
464+ { -- | Short description for the example.
465+ _exampleSummary :: Maybe Text
466+
467+ -- | Long description for the example.
468+ -- CommonMark syntax MAY be used for rich text representation.
469+ , _exampleDescription :: Maybe Text
470+
471+ -- | Embedded literal example.
472+ -- The '_exampleValue' field and '_exampleExternalValue' field are mutually exclusive.
473+ --
474+ -- To represent examples of media types that cannot naturally represented in JSON or YAML,
475+ -- use a string value to contain the example, escaping where necessary.
476+ , _exampleValue :: Maybe Value
477+
478+ -- | A URL that points to the literal example.
479+ -- This provides the capability to reference examples that cannot easily be included
480+ -- in JSON or YAML documents. The '_exampleValue' field
481+ -- and '_exampleExternalValue' field are mutually exclusive.
482+ , _exampleExternalValue :: Maybe URL
483+ } deriving (Eq, Show, Generic, Typeable, Data)
484+
415485-- | Items for @'SwaggerArray'@ schemas.
416486--
417487-- @'SwaggerItemsPrimitive'@ should be used only for query params, headers and path pieces.
@@ -633,6 +703,8 @@ data NamedSchema = NamedSchema
633703-- | Regex pattern for @string@ type.
634704type Pattern = Text
635705
706+-- TODO examples for params
707+
636708data ParamSchema (t :: SwaggerKind *) = ParamSchema
637709 { -- | Declares the value of the parameter that the server will use if none is provided,
638710 -- for example a @"count"@ to control the number of results per page might default to @100@
@@ -735,22 +807,6 @@ data Header = Header
735807 , _headerParamSchema :: ParamSchema ('SwaggerKindNormal Header)
736808 } deriving (Eq, Show, Generic, Data, Typeable)
737809
738−data Example = Example { getExample :: Map MediaType Value }
739− deriving (Eq, Show, Generic, Typeable)
740−
741−exampleConstr :: Constr
742−exampleConstr = mkConstr exampleDataType "Example" ["getExample"] Prefix
743−
744−exampleDataType :: DataType
745−exampleDataType = mkDataType "Data.Swagger.Example" [exampleConstr]
746−
747−instance Data Example where
748− gunfold k z c = case constrIndex c of
749− 1 -> k (z (\m -> Example (Map.mapKeys fromString m)))
750− _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type Example."
751− toConstr (Example _) = exampleConstr
752− dataTypeOf _ = exampleDataType
753−
754810-- | The location of the API key.
755811data ApiKeyLocation
756812 = ApiKeyQuery
@@ -898,6 +954,8 @@ deriveGeneric ''SecurityScheme
898954deriveGeneric ''Schema
899955deriveGeneric ''ParamSchema
900956deriveGeneric ''Swagger
957+deriveGeneric ''Example
958+deriveGeneric ''Encoding
901959
902960-- =======================================================================
903961-- Monoid instances
@@ -981,21 +1039,21 @@ instance Monoid MediaTypeObject where
9811039 mempty = genericMempty
9821040 mappend = (<>)
9831041
984−instance Semigroup ExternalDocs where
1042+instance Semigroup Encoding where
9851043 (<>) = genericMappend
986−instance Monoid ExternalDocs where
1044+instance Monoid Encoding where
9871045 mempty = genericMempty
9881046 mappend = (<>)
9891047
990−instance Semigroup Operation where
1048+instance Semigroup ExternalDocs where
9911049 (<>) = genericMappend
992−instance Monoid Operation where
1050+instance Monoid ExternalDocs where
9931051 mempty = genericMempty
9941052 mappend = (<>)
9951053
996−instance Semigroup Example where
1054+instance Semigroup Operation where
9971055 (<>) = genericMappend
998−instance Monoid Example where
1056+instance Monoid Operation where
9991057 mempty = genericMempty
10001058 mappend = (<>)
10011059
@@ -1251,7 +1309,12 @@ instance ToJSON MediaTypeObject where
12511309 toEncoding = sopSwaggerGenericToEncoding
12521310
12531311instance ToJSON Example where
1254− toJSON = toJSON . Map.mapKeys show . getExample
1312+ toJSON = sopSwaggerGenericToJSON
1313+ toEncoding = sopSwaggerGenericToEncoding
1314+
1315+instance ToJSON Encoding where
1316+ toJSON = sopSwaggerGenericToJSON
1317+ toEncoding = sopSwaggerGenericToEncoding
12551318
12561319instance ToJSON SecurityDefinitions where
12571320 toJSON (SecurityDefinitions sd) = toJSON sd
@@ -1267,6 +1330,8 @@ instance ToJSON (Referenced Schema) where toJSON = referencedToJSON "#/compone
12671330instance ToJSON (Referenced Param) where toJSON = referencedToJSON "#/components/parameters/"
12681331instance ToJSON (Referenced Response) where toJSON = referencedToJSON "#/components/responses/"
12691332instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
1333+instance ToJSON (Referenced Example) where toJSON = referencedToJSON "#/components/examples/"
1334+instance ToJSON (Referenced Header) where toJSON = referencedToJSON "#/components/headers/"
12701335
12711336instance ToJSON (SwaggerType t) where
12721337 toJSON SwaggerArray = "array"
@@ -1408,9 +1473,7 @@ instance FromJSON Responses where
14081473 parseJSON _ = empty
14091474
14101475instance FromJSON Example where
1411− parseJSON js = do
1412− m <- parseJSON js
1413− pure $ Example (Map.mapKeys fromString m)
1476+ parseJSON = sopSwaggerGenericParseJSON
14141477
14151478instance FromJSON Response where
14161479 parseJSON = sopSwaggerGenericParseJSON
@@ -1427,6 +1490,9 @@ instance FromJSON RequestBody where
14271490instance FromJSON MediaTypeObject where
14281491 parseJSON = sopSwaggerGenericParseJSON
14291492
1493+instance FromJSON Encoding where
1494+ parseJSON = sopSwaggerGenericParseJSON
1495+
14301496instance FromJSON SecurityDefinitions where
14311497 parseJSON js = SecurityDefinitions <$> parseJSON js
14321498
@@ -1450,7 +1516,9 @@ referencedParseJSON _ _ = fail "referenceParseJSON: not an object"
14501516instance FromJSON (Referenced Schema) where parseJSON = referencedParseJSON "#/components/schemas/"
14511517instance FromJSON (Referenced Param) where parseJSON = referencedParseJSON "#/components/parameters/"
14521518instance FromJSON (Referenced Response) where parseJSON = referencedParseJSON "#/components/responses/"
1453−instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies"
1519+instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies/"
1520+instance FromJSON (Referenced Example) where parseJSON = referencedParseJSON "#/components/examples/"
1521+instance FromJSON (Referenced Header) where parseJSON = referencedParseJSON "#/components/headers/"
14541522
14551523instance FromJSON Xml where
14561524 parseJSON = genericParseJSON (jsonPrefix "xml")
@@ -1513,6 +1581,10 @@ instance HasSwaggerAesonOptions Schema where
15131581 swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
15141582instance HasSwaggerAesonOptions Swagger where
15151583 swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("openapi", "3.0.3")]
1584+instance HasSwaggerAesonOptions Example where
1585+ swaggerAesonOptions _ = mkSwaggerAesonOptions "example"
1586+instance HasSwaggerAesonOptions Encoding where
1587+ swaggerAesonOptions _ = mkSwaggerAesonOptions "encoding"
15161588
15171589instance HasSwaggerAesonOptions (ParamSchema ('SwaggerKindNormal t)) where
15181590 swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"