git.iko.soy/typeable/openapi3
on master help sign in
Derive FromJSON instances too
commitf508aa282933fdf216836a7c743e375b8b9a4449 authorOleg Grenrus <oleg.grenrus@iki.fi> dateTue 8 Mar 2016, 11:48 (11 years ago) parente2a9cc2
7 files changed+344−152
src/Data/Swagger/Internal.hs+167−95 src/Data/Swagger/Internal/AesonUtils.hs+164−16 src/Data/Swagger/Internal/Schema.hs+2−1 src/Data/Swagger/Internal/Utils.hs−31 src/Data/Swagger/Lens.hs+8−7 swagger2.cabal−1 test/Data/Swagger/ParamSchemaSpec.hs+3−1
src/Data/Swagger/Internal.hs+167−95
@@ -8,6 +8,7 @@
88{-# LANGUAGE GADTs #-}
99{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1010{-# LANGUAGE OverloadedStrings #-}
11+{-# LANGUAGE PolyKinds #-}
1112{-# LANGUAGE RecordWildCards #-}
1213{-# LANGUAGE ScopedTypeVariables #-}
1314{-# LANGUAGE StandaloneDeriving #-}
@@ -48,6 +49,10 @@ import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
4849
4950import Generics.SOP.TH (deriveGeneric)
5051import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToJSON
52+ ,sopSwaggerGenericToJSONWithOpts
53+ ,sopSwaggerGenericParseJSON
54+ ,HasSwaggerAesonOptions(..)
55+ ,AesonDefaultValue(..)
5156 ,mkSwaggerAesonOptions
5257 ,saoAdditionalPairs
5358 ,saoSubObject)
@@ -343,8 +348,8 @@ data ParamOtherSchema = ParamOtherSchema
343348 -- Default value is @False@.
344349 , _paramOtherSchemaAllowEmptyValue :: Maybe Bool
345350
346− , _paramOtherSchemaParamSchema :: ParamSchema ParamOtherSchema
347− } deriving (Eq, Show, Generic, Data, Typeable)
351+ , _paramOtherSchemaParamSchema :: ParamSchema SwaggerKindParamOtherSchema
352+ } deriving (Eq, Show, Generic, Typeable, Data)
348353
349354-- | Items for @'SwaggerArray'@ schemas.
350355--
@@ -357,9 +362,9 @@ data ParamOtherSchema = ParamOtherSchema
357362--
358363-- @'SwaggerItemsArray'@ should be used to specify tuple @'Schema'@s.
359364data SwaggerItems t where
360− SwaggerItemsPrimitive :: Maybe (CollectionFormat t) -> ParamSchema t -> SwaggerItems t
361− SwaggerItemsObject :: Referenced Schema -> SwaggerItems Schema
362− SwaggerItemsArray :: [Referenced Schema] -> SwaggerItems Schema
365+ SwaggerItemsPrimitive :: Maybe (CollectionFormat k) -> ParamSchema k-> SwaggerItems k
366+ SwaggerItemsObject :: Referenced Schema -> SwaggerItems SwaggerKindSchema
367+ SwaggerItemsArray :: [Referenced Schema] -> SwaggerItems SwaggerKindSchema
363368 deriving (Typeable)
364369
365370deriving instance Eq (SwaggerItems t)
@@ -369,17 +374,66 @@ deriving instance Show (SwaggerItems t)
369374swaggerItemsPrimitiveConstr :: Constr
370375swaggerItemsPrimitiveConstr = mkConstr swaggerItemsDataType "SwaggerItemsPrimitive" [] Prefix
371376
377+swaggerItemsObjectConstr :: Constr
378+swaggerItemsObjectConstr = mkConstr swaggerItemsDataType "SwaggerItemsObject" [] Prefix
379+
380+swaggerItemsArrayConstr :: Constr
381+swaggerItemsArrayConstr = mkConstr swaggerItemsDataType "SwaggerItemsArray" [] Prefix
382+
372383swaggerItemsDataType :: DataType
373384swaggerItemsDataType = mkDataType "Data.Swagger.SwaggerItems" [swaggerItemsPrimitiveConstr]
374385
375−instance OVERLAPPABLE_ Data t => Data (SwaggerItems t) where
386+-- Note: unfortunately we have to write these Data instances by hand,
387+-- to get better contexts / avoid duplicate name when using standalone deriving
388+
389+instance Data t => Data (SwaggerItems (SwaggerKindNormal t)) where
390+ -- TODO: define gfoldl
376391 gunfold k z c = case constrIndex c of
377392 1 -> k (k (z SwaggerItemsPrimitive))
378393 _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type (SwaggerItems t)."
379394 toConstr _ = swaggerItemsPrimitiveConstr
380395 dataTypeOf _ = swaggerItemsDataType
381396
382−deriving instance Data (SwaggerItems Schema)
397+-- SwaggerItems SwaggerKindParamOtherSchema can be constructed using SwaggerItemsPrimitive only
398+instance Data (SwaggerItems SwaggerKindParamOtherSchema) where
399+ -- TODO: define gfoldl
400+ gunfold k z c = case constrIndex c of
401+ 1 -> k (k (z SwaggerItemsPrimitive))
402+ _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type (SwaggerItems SwaggerKindParamOtherSchema)."
403+ toConstr _ = swaggerItemsPrimitiveConstr
404+ dataTypeOf _ = swaggerItemsDataType
405+
406+instance Data (SwaggerItems SwaggerKindSchema) where
407+ gfoldl _ _ (SwaggerItemsPrimitive _ _) = error $ " Data.Data.gfoldl: Constructor SwaggerItemsPrimitive used to construct SwaggerItems SwaggerKindSchema"
408+ gfoldl k z (SwaggerItemsObject ref) = z SwaggerItemsObject `k` ref
409+ gfoldl k z (SwaggerItemsArray ref) = z SwaggerItemsArray `k` ref
410+
411+ gunfold k z c = case constrIndex c of
412+ 1 -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type (SwaggerItems SwaggerKindSchema)"
413+ 2 -> k (z SwaggerItemsObject)
414+ 3 -> k (z SwaggerItemsArray)
415+
416+ toConstr (SwaggerItemsObject _) = swaggerItemsObjectConstr
417+ toConstr (SwaggerItemsArray _) = swaggerItemsArrayConstr
418+
419+ dataTypeOf _ = swaggerItemsDataType
420+
421+-- | Type used as a kind to avoid overlapping instances.
422+data SwaggerKind t
423+ = SwaggerKindNormal t
424+ | SwaggerKindParamOtherSchema
425+ | SwaggerKindSchema
426+
427+#if __GLASGLOW_HASKELL__ < 710
428+deriving instance Typeable 'SwaggerKindNormal
429+deriving instance Typeable 'SwaggerKindParamOtherSchema
430+deriving instance Typeable 'SwaggerKindSchema
431+#endif
432+
433+type family SwaggerKindType (k :: SwaggerKind *) :: *
434+type instance SwaggerKindType (SwaggerKindNormal t) = t
435+type instance SwaggerKindType SwaggerKindSchema = Schema
436+type instance SwaggerKindType SwaggerKindParamOtherSchema = ParamOtherSchema
383437
384438data SwaggerType t where
385439 SwaggerString :: SwaggerType t
@@ -387,9 +441,9 @@ data SwaggerType t where
387441 SwaggerInteger :: SwaggerType t
388442 SwaggerBoolean :: SwaggerType t
389443 SwaggerArray :: SwaggerType t
390− SwaggerFile :: SwaggerType ParamOtherSchema
391− SwaggerNull :: SwaggerType Schema
392− SwaggerObject :: SwaggerType Schema
444+ SwaggerFile :: SwaggerType SwaggerKindParamOtherSchema
445+ SwaggerNull :: SwaggerType SwaggerKindSchema
446+ SwaggerObject :: SwaggerType SwaggerKindSchema
393447 deriving (Typeable)
394448
395449deriving instance Eq (SwaggerType t)
@@ -401,30 +455,30 @@ swaggerTypeConstr t = mkConstr (dataTypeOf t) (show t) [] Prefix
401455swaggerTypeDataType :: Data (SwaggerType t) => SwaggerType t -> DataType
402456swaggerTypeDataType _ = mkDataType "Data.Swagger.SwaggerType" swaggerTypeConstrs
403457
404−swaggerCommonTypes :: [SwaggerType t]
458+swaggerCommonTypes :: [SwaggerType k]
405459swaggerCommonTypes = [SwaggerString, SwaggerNumber, SwaggerInteger, SwaggerBoolean, SwaggerArray]
406460
407−swaggerParamTypes :: [SwaggerType ParamOtherSchema]
461+swaggerParamTypes :: [SwaggerType SwaggerKindParamOtherSchema]
408462swaggerParamTypes = swaggerCommonTypes ++ [SwaggerFile]
409463
410−swaggerSchemaTypes :: [SwaggerType Schema]
464+swaggerSchemaTypes :: [SwaggerType SwaggerKindSchema]
411465swaggerSchemaTypes = swaggerCommonTypes ++ [error "SwaggerFile is invalid SwaggerType Schema", SwaggerNull, SwaggerObject]
412466
413467swaggerTypeConstrs :: [Constr]
414−swaggerTypeConstrs = map swaggerTypeConstr (swaggerCommonTypes :: [SwaggerType Schema])
468+swaggerTypeConstrs = map swaggerTypeConstr (swaggerCommonTypes :: [SwaggerType SwaggerKindSchema])
415469 ++ [swaggerTypeConstr SwaggerFile, swaggerTypeConstr SwaggerNull, swaggerTypeConstr SwaggerObject]
416470
417−instance OVERLAPPABLE_ Typeable t => Data (SwaggerType t) where
471+instance Typeable t => Data (SwaggerType (SwaggerKindNormal t)) where
418472 gunfold = gunfoldEnum "SwaggerType" swaggerCommonTypes
419473 toConstr = swaggerTypeConstr
420474 dataTypeOf = swaggerTypeDataType
421475
422−instance OVERLAPPABLE_ Data (SwaggerType ParamOtherSchema) where
476+instance Data (SwaggerType SwaggerKindParamOtherSchema) where
423477 gunfold = gunfoldEnum "SwaggerType ParamOtherSchema" swaggerParamTypes
424478 toConstr = swaggerTypeConstr
425479 dataTypeOf = swaggerTypeDataType
426480
427−instance OVERLAPPABLE_ Data (SwaggerType Schema) where
481+instance Data (SwaggerType SwaggerKindSchema) where
428482 gunfold = gunfoldEnum "SwaggerType Schema" swaggerSchemaTypes
429483 toConstr = swaggerTypeConstr
430484 dataTypeOf = swaggerTypeDataType
@@ -464,7 +518,7 @@ data CollectionFormat t where
464518 -- Corresponds to multiple parameter instances
465519 -- instead of multiple values for a single instance @foo=bar&foo=baz@.
466520 -- This is valid only for parameters in @'ParamQuery'@ or @'ParamFormData'@.
467− CollectionMulti :: CollectionFormat ParamOtherSchema
521+ CollectionMulti :: CollectionFormat SwaggerKindParamOtherSchema
468522 deriving (Typeable)
469523
470524deriving instance Eq (CollectionFormat t)
@@ -480,12 +534,12 @@ collectionFormatDataType = mkDataType "Data.Swagger.CollectionFormat" $
480534collectionCommonFormats :: [CollectionFormat t]
481535collectionCommonFormats = [ CollectionCSV, CollectionSSV, CollectionTSV, CollectionPipes ]
482536
483−instance OVERLAPPABLE_ Data t => Data (CollectionFormat t) where
537+instance Data t => Data (CollectionFormat (SwaggerKindNormal t)) where
484538 gunfold = gunfoldEnum "CollectionFormat" collectionCommonFormats
485539 toConstr = collectionFormatConstr
486540 dataTypeOf _ = collectionFormatDataType
487541
488−deriving instance OVERLAPPABLE_ Data (CollectionFormat ParamOtherSchema)
542+deriving instance Data (CollectionFormat SwaggerKindParamOtherSchema)
489543
490544type ParamName = Text
491545
@@ -507,7 +561,7 @@ data Schema = Schema
507561 , _schemaMaxProperties :: Maybe Integer
508562 , _schemaMinProperties :: Maybe Integer
509563
510− , _schemaParamSchema :: ParamSchema Schema
564+ , _schemaParamSchema :: ParamSchema SwaggerKindSchema
511565 } deriving (Eq, Show, Generic, Data, Typeable)
512566
513567-- | A @'Schema'@ with an optional name.
@@ -520,7 +574,7 @@ data NamedSchema = NamedSchema
520574-- | Regex pattern for @string@ type.
521575type Pattern = Text
522576
523−data ParamSchema t = ParamSchema
577+data ParamSchema (t :: SwaggerKind *) = ParamSchema
524578 { -- | Declares the value of the parameter that the server will use if none is provided,
525579 -- for example a @"count"@ to control the number of results per page might default to @100@
526580 -- if not supplied by the client in the request.
@@ -545,7 +599,7 @@ data ParamSchema t = ParamSchema
545599 , _paramSchemaMultipleOf :: Maybe Scientific
546600 } deriving (Eq, Show, Generic, Typeable)
547601
548−deriving instance (Data t, Data (SwaggerType t), Data (SwaggerItems t)) => Data (ParamSchema t)
602+deriving instance (Typeable k, Data (SwaggerKindType k), Data (SwaggerType k), Data (SwaggerItems k)) => Data (ParamSchema k)
549603
550604data Xml = Xml
551605 { -- | Replaces the name of the element/attribute used for the described schema property.
@@ -621,7 +675,7 @@ data Header = Header
621675 { -- | A short description of the header.
622676 _headerDescription :: Maybe Text
623677
624− , _headerParamSchema :: ParamSchema Header
678+ , _headerParamSchema :: ParamSchema (SwaggerKindNormal Header)
625679 } deriving (Eq, Show, Generic, Data, Typeable)
626680
627681data Example = Example { getExample :: Map MediaType Value }
@@ -827,10 +881,6 @@ instance SwaggerMonoid ParamLocation where
827881 swaggerMempty = ParamQuery
828882 swaggerMappend _ y = y
829883
830−instance OVERLAPPING_ SwaggerMonoid (HashMap FilePath PathItem) where
831− swaggerMempty = HashMap.empty
832− swaggerMappend = HashMap.unionWith mappend
833−
834884instance OVERLAPPING_ SwaggerMonoid (InsOrdHashMap FilePath PathItem) where
835885 swaggerMempty = InsOrdHashMap.empty
836886 swaggerMappend = InsOrdHashMap.unionWith mappend
@@ -931,8 +981,7 @@ instance ToJSON OAuth2Flow where
931981 , "tokenUrl" .= tokenUrl ]
932982
933983instance ToJSON OAuth2Params where
934− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "oauth2" &
935− saoSubObject ?~ "flow"
984+ toJSON = sopSwaggerGenericToJSON
936985
937986instance ToJSON SecuritySchemeType where
938987 toJSON SecuritySchemeBasic
@@ -945,22 +994,18 @@ instance ToJSON SecuritySchemeType where
945994 <+> object [ "type" .= ("oauth2" :: Text) ]
946995
947996instance ToJSON Swagger where
948− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "swagger" &
949− saoAdditionalPairs .~ [("swagger", "2.0")]
997+ toJSON = sopSwaggerGenericToJSON
950998
951999instance ToJSON SecurityScheme where
952− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "securityScheme" &
953− saoSubObject ?~ "type"
1000+ toJSON = sopSwaggerGenericToJSON
9541001
9551002instance ToJSON Schema where
956− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "schema" &
957− saoSubObject ?~ "paramSchema"
1003+ toJSON = sopSwaggerGenericToJSON
9581004
9591005instance ToJSON Header where
960− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "header" &
961− saoSubObject ?~ "paramSchema"
1006+ toJSON = sopSwaggerGenericToJSON
9621007
963−instance ToJSON (SwaggerItems t) where
1008+instance ToJSON (ParamSchema t) => ToJSON (SwaggerItems t) where
9641009 toJSON (SwaggerItemsPrimitive fmt schema) = object
9651010 [ "collectionFormat" .= fmt
9661011 , "items" .= schema ]
@@ -977,29 +1022,26 @@ instance ToJSON MimeList where
9771022 toJSON (MimeList xs) = toJSON (map show xs)
9781023
9791024instance ToJSON Param where
980− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "param" &
981− saoSubObject ?~ "schema"
1025+ toJSON = sopSwaggerGenericToJSON
9821026
9831027instance ToJSON ParamAnySchema where
9841028 toJSON (ParamBody s) = object [ "in" .= ("body" :: Text), "schema" .= s ]
9851029 toJSON (ParamOther s) = toJSON s
9861030
9871031instance ToJSON ParamOtherSchema where
988− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "paramOtherSchema" &
989− saoSubObject ?~ "paramSchema"
1032+ toJSON = sopSwaggerGenericToJSON
9901033
9911034instance ToJSON Responses where
992− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "responses" &
993− saoSubObject ?~ "responses"
1035+ toJSON = sopSwaggerGenericToJSON
9941036
9951037instance ToJSON Response where
996− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "response"
1038+ toJSON = sopSwaggerGenericToJSON
9971039
9981040instance ToJSON Operation where
999− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "operation"
1041+ toJSON = sopSwaggerGenericToJSON
10001042
10011043instance ToJSON PathItem where
1002− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "pathItem"
1044+ toJSON = sopSwaggerGenericToJSON
10031045
10041046instance ToJSON Example where
10051047 toJSON = toJSON . Map.mapKeys show . getExample
@@ -1032,9 +1074,10 @@ instance ToJSON (CollectionFormat t) where
10321074 toJSON CollectionPipes = "pipes"
10331075 toJSON CollectionMulti = "multi"
10341076
1035−instance ToJSON (ParamSchema t) where
1036− toJSON = sopSwaggerGenericToJSON $ mkSwaggerAesonOptions "paramSchema" &
1037− saoSubObject ?~ "items"
1077+instance ToJSON (ParamSchema k) where
1078+ -- TODO: this is a bit fishy, why we need sub object only in `ToJSON`?
1079+ toJSON = sopSwaggerGenericToJSONWithOpts $
1080+ mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"
10381081
10391082-- =======================================================================
10401083-- Manual FromJSON instances
@@ -1054,7 +1097,7 @@ instance FromJSON OAuth2Flow where
10541097 parseJSON _ = empty
10551098
10561099instance FromJSON OAuth2Params where
1057− parseJSON = genericParseJSONWithSub "flow" (jsonPrefix "oauth2")
1100+ parseJSON = sopSwaggerGenericParseJSON
10581101
10591102instance FromJSON SecuritySchemeType where
10601103 parseJSON js@(Object o) = do
@@ -1067,38 +1110,28 @@ instance FromJSON SecuritySchemeType where
10671110 parseJSON _ = empty
10681111
10691112instance FromJSON Swagger where
1070− parseJSON js@(Object o) = do
1071− (version :: Text) <- o .: "swagger"
1072− when (version /= "2.0") empty
1073− (genericParseJSON (jsonPrefix "swagger")
1074− `withDefaults` [ "consumes" .= (mempty :: MimeList)
1075− , "produces" .= (mempty :: MimeList)
1076− , "security" .= ([] :: [SecurityRequirement])
1077− , "tags" .= ([] :: [Tag])
1078− , "definitions" .= (mempty :: Definitions Schema)
1079− , "parameters" .= (mempty :: Definitions Param)
1080− , "responses" .= (mempty :: Definitions Response)
1081− , "securityDefinitions" .= (mempty :: Definitions SecurityScheme)
1082− ] ) js
1083− parseJSON _ = empty
1113+ parseJSON = sopSwaggerGenericParseJSON
10841114
10851115instance FromJSON SecurityScheme where
1086− parseJSON = genericParseJSONWithSub "type" (jsonPrefix "securityScheme")
1116+ parseJSON = sopSwaggerGenericParseJSON
10871117
10881118instance FromJSON Schema where
1089− parseJSON = genericParseJSONWithSub "paramSchema" (jsonPrefix "schema")
1090− `withDefaults` [ "properties" .= (mempty :: InsOrdHashMap Text Schema)
1091− , "required" .= ([] :: [ParamName]) ]
1119+ parseJSON = sopSwaggerGenericParseJSON
10921120
10931121instance FromJSON Header where
1094− parseJSON = genericParseJSONWithSub "paramSchema" (jsonPrefix "header")
1122+ parseJSON = sopSwaggerGenericParseJSON
10951123
1096−instance OVERLAPPABLE_ (FromJSON (CollectionFormat t), FromJSON (ParamSchema t)) => FromJSON (SwaggerItems t) where
1124+instance (FromJSON (CollectionFormat (SwaggerKindNormal t)), FromJSON (ParamSchema (SwaggerKindNormal t))) => FromJSON (SwaggerItems (SwaggerKindNormal t)) where
10971125 parseJSON = withObject "SwaggerItemsPrimitive" $ \o -> SwaggerItemsPrimitive
10981126 <$> o .:? "collectionFormat"
10991127 <*> (o .: "items" >>= parseJSON)
11001128
1101−instance OVERLAPPABLE_ FromJSON (SwaggerItems Schema) where
1129+instance FromJSON (SwaggerItems SwaggerKindParamOtherSchema) where
1130+ parseJSON = withObject "SwaggerItemsPrimitive" $ \o -> SwaggerItemsPrimitive
1131+ <$> o .:? "collectionFormat"
1132+ <*> ((o .: "items" >>= parseJSON) <|> fail ("foo" ++ show o))
1133+
1134+instance FromJSON (SwaggerItems SwaggerKindSchema) where
11021135 parseJSON js@(Object _) = SwaggerItemsObject <$> parseJSON js
11031136 parseJSON js@(Array _) = SwaggerItemsArray <$> parseJSON js
11041137 parseJSON _ = empty
@@ -1116,7 +1149,7 @@ instance FromJSON MimeList where
11161149 parseJSON js = (MimeList . map fromString) <$> parseJSON js
11171150
11181151instance FromJSON Param where
1119− parseJSON = genericParseJSONWithSub "schema" (jsonPrefix "param")
1152+ parseJSON = sopSwaggerGenericParseJSON
11201153
11211154instance FromJSON ParamAnySchema where
11221155 parseJSON js@(Object o) = do
@@ -1129,7 +1162,7 @@ instance FromJSON ParamAnySchema where
11291162 parseJSON _ = empty
11301163
11311164instance FromJSON ParamOtherSchema where
1132− parseJSON = genericParseJSONWithSub "paramSchema" (jsonPrefix "paramOtherSchema")
1165+ parseJSON = sopSwaggerGenericParseJSON
11331166
11341167instance FromJSON Responses where
11351168 parseJSON (Object o) = Responses
@@ -1143,18 +1176,13 @@ instance FromJSON Example where
11431176 pure $ Example (Map.mapKeys fromString m)
11441177
11451178instance FromJSON Response where
1146− parseJSON = genericParseJSON (jsonPrefix "response")
1147− `withDefaults` [ "headers" .= (mempty :: InsOrdHashMap HeaderName Header) ]
1179+ parseJSON = sopSwaggerGenericParseJSON
11481180
11491181instance FromJSON Operation where
1150− parseJSON = genericParseJSON (jsonPrefix "operation")
1151− `withDefaults` [ "security" .= ([] :: [SecurityRequirement])
1152− , "tags" .= ([] :: [Tag])
1153− , "parameters" .= ([] :: [Referenced Param]) ]
1182+ parseJSON = sopSwaggerGenericParseJSON
11541183
11551184instance FromJSON PathItem where
1156− parseJSON = genericParseJSON (jsonPrefix "pathItem")
1157− `withDefaults` [ "parameters" .= ([] :: [Param]) ]
1185+ parseJSON = sopSwaggerGenericParseJSON
11581186
11591187instance FromJSON Reference where
11601188 parseJSON (Object o) = Reference <$> o .: "$ref"
@@ -1180,28 +1208,31 @@ instance FromJSON (Referenced Response) where parseJSON = referencedParseJSON "#
11801208instance FromJSON Xml where
11811209 parseJSON = genericParseJSON (jsonPrefix "xml")
11821210
1183−instance FromJSON (SwaggerType Schema) where
1211+instance FromJSON (SwaggerType SwaggerKindSchema) where
11841212 parseJSON = parseOneOf [SwaggerString, SwaggerInteger, SwaggerNumber, SwaggerBoolean, SwaggerArray, SwaggerNull, SwaggerObject]
11851213
1186−instance FromJSON (SwaggerType ParamOtherSchema) where
1214+instance FromJSON (SwaggerType SwaggerKindParamOtherSchema) where
11871215 parseJSON = parseOneOf [SwaggerString, SwaggerInteger, SwaggerNumber, SwaggerBoolean, SwaggerArray, SwaggerFile]
11881216
1189−instance OVERLAPPABLE_ FromJSON (SwaggerType t) where
1217+instance FromJSON (SwaggerType (SwaggerKindNormal t)) where
11901218 parseJSON = parseOneOf [SwaggerString, SwaggerInteger, SwaggerNumber, SwaggerBoolean, SwaggerArray]
11911219
1192−instance OVERLAPPABLE_ FromJSON (CollectionFormat t) where
1220+instance FromJSON (CollectionFormat (SwaggerKindNormal t)) where
11931221 parseJSON = parseOneOf [CollectionCSV, CollectionSSV, CollectionTSV, CollectionPipes]
11941222
1195−instance FromJSON (CollectionFormat ParamOtherSchema) where
1223+-- NOTE: There aren't collections of 'Schema'
1224+--instance FromJSON (CollectionFormat (SwaggerKindSchema)) where
1225+-- parseJSON = parseOneOf [CollectionCSV, CollectionSSV, CollectionTSV, CollectionPipes]
1226+
1227+instance FromJSON (CollectionFormat SwaggerKindParamOtherSchema) where
11961228 parseJSON = parseOneOf [CollectionCSV, CollectionSSV, CollectionTSV, CollectionPipes, CollectionMulti]
11971229
1198−-- NOTE: The constraints @FromJSON (SwaggerType t)@ and
1199−-- @FromJSON (SwaggerItems t)@ are necessary here!
1200−-- Without the constraint the general instance will be used
1201−-- that only accepts common types (i.e. NOT object, null or file)
1202−-- and primitive array items.
1203−instance (FromJSON (SwaggerType t), FromJSON (SwaggerItems t)) => FromJSON (ParamSchema t) where
1204− parseJSON = genericParseJSONWithSub "items" (jsonPrefix "ParamSchema")
1230+instance (FromJSON (SwaggerType (SwaggerKindNormal t)), FromJSON (SwaggerItems (SwaggerKindNormal t))) => FromJSON (ParamSchema (SwaggerKindNormal t)) where
1231+ parseJSON = sopSwaggerGenericParseJSON
1232+instance FromJSON (ParamSchema SwaggerKindParamOtherSchema) where
1233+ parseJSON = sopSwaggerGenericParseJSON
1234+instance FromJSON (ParamSchema SwaggerKindSchema) where
1235+ parseJSON = sopSwaggerGenericParseJSON
12051236
12061237-------------------------------------------------------------------------------
12071238-- TH splices
@@ -1219,3 +1250,44 @@ deriveGeneric ''SecurityScheme
12191250deriveGeneric ''Schema
12201251deriveGeneric ''ParamSchema
12211252deriveGeneric ''Swagger
1253+
1254+instance HasSwaggerAesonOptions Header where
1255+ swaggerAesonOptions _ = mkSwaggerAesonOptions "header" & saoSubObject ?~ "paramSchema"
1256+instance HasSwaggerAesonOptions OAuth2Params where
1257+ swaggerAesonOptions _ = mkSwaggerAesonOptions "oauth2" & saoSubObject ?~ "flow"
1258+instance HasSwaggerAesonOptions Operation where
1259+ swaggerAesonOptions _ = mkSwaggerAesonOptions "operation"
1260+instance HasSwaggerAesonOptions Param where
1261+ swaggerAesonOptions _ = mkSwaggerAesonOptions "param" & saoSubObject ?~ "schema"
1262+instance HasSwaggerAesonOptions ParamOtherSchema where
1263+ swaggerAesonOptions _ = mkSwaggerAesonOptions "paramOtherSchema" & saoSubObject ?~ "paramSchema"
1264+instance HasSwaggerAesonOptions PathItem where
1265+ swaggerAesonOptions _ = mkSwaggerAesonOptions "pathItem"
1266+instance HasSwaggerAesonOptions Response where
1267+ swaggerAesonOptions _ = mkSwaggerAesonOptions "response"
1268+instance HasSwaggerAesonOptions Responses where
1269+ swaggerAesonOptions _ = mkSwaggerAesonOptions "responses" & saoSubObject ?~ "responses"
1270+instance HasSwaggerAesonOptions SecurityScheme where
1271+ swaggerAesonOptions _ = mkSwaggerAesonOptions "securityScheme" & saoSubObject ?~ "type"
1272+instance HasSwaggerAesonOptions Schema where
1273+ swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
1274+instance HasSwaggerAesonOptions Swagger where
1275+ swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("swagger", "2.0")]
1276+
1277+instance HasSwaggerAesonOptions (ParamSchema (SwaggerKindNormal t)) where
1278+ swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"
1279+instance HasSwaggerAesonOptions (ParamSchema SwaggerKindParamOtherSchema) where
1280+ swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"
1281+-- NOTE: Schema doesn't have 'items' sub object!
1282+instance HasSwaggerAesonOptions (ParamSchema SwaggerKindSchema) where
1283+ swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema"
1284+
1285+instance AesonDefaultValue (ParamSchema s)
1286+instance AesonDefaultValue OAuth2Flow
1287+instance AesonDefaultValue Responses
1288+instance AesonDefaultValue ParamAnySchema
1289+instance AesonDefaultValue SecuritySchemeType
1290+instance AesonDefaultValue (SwaggerType a)
1291+instance AesonDefaultValue MimeList where defaultValue = Just mempty
1292+instance AesonDefaultValue Info
1293+instance AesonDefaultValue ParamLocation
src/Data/Swagger/Internal/AesonUtils.hs+164−16
@@ -6,8 +6,12 @@
66{-# LANGUAGE TemplateHaskell #-}
77module Data.Swagger.Internal.AesonUtils (
88 -- * Generic functions
9+ AesonDefaultValue(..),
910 sopSwaggerGenericToJSON,
11+ sopSwaggerGenericToJSONWithOpts,
12+ sopSwaggerGenericParseJSON,
1013 -- * Options
14+ HasSwaggerAesonOptions(..),
1115 SwaggerAesonOptions,
1216 mkSwaggerAesonOptions,
1317 saoPrefix,
@@ -18,15 +22,20 @@ module Data.Swagger.Internal.AesonUtils (
1822import Prelude ()
1923import Prelude.Compat
2024
21−import Control.Lens (makeLenses, (^.))
22−import Data.Aeson (ToJSON(..), Value(..), object)
23−import Data.Text (Text)
24−import Data.Char (toLower, isUpper)
25+import Control.Applicative ((<|>))
26+import Control.Lens (makeLenses, (^.))
27+import Control.Monad (unless)
28+import Data.Aeson (ToJSON(..), FromJSON(..), Value(..), Object, object, (.:), (.:?), (.!=), withObject)
29+import Data.Aeson.Types (Parser)
30+import Data.Char (toLower, isUpper)
31+import Data.Text (Text)
2532
2633import Generics.SOP
2734
2835import qualified Data.Text as T
2936import qualified Data.HashMap.Strict as HM
37+import qualified Data.Set as Set
38+import qualified Data.HashMap.Strict.InsOrd as InsOrd
3039
3140-------------------------------------------------------------------------------
3241-- SwaggerAesonOptions
@@ -45,10 +54,31 @@ mkSwaggerAesonOptions pfx = SwaggerAesonOptions pfx [] Nothing
4554
4655makeLenses ''SwaggerAesonOptions
4756
57+class (Generic a, All2 AesonDefaultValue (Code a)) => HasSwaggerAesonOptions a where
58+ swaggerAesonOptions :: proxy a -> SwaggerAesonOptions
59+
60+ -- So far we use only default definitions
61+ aesonDefaults :: proxy a -> POP Maybe (Code a)
62+ aesonDefaults _ = hcpure (Proxy :: Proxy AesonDefaultValue) defaultValue
63+
4864-------------------------------------------------------------------------------
4965-- Generics
5066-------------------------------------------------------------------------------
5167
68+class AesonDefaultValue a where
69+ defaultValue :: Maybe a
70+ defaultValue = Nothing
71+
72+instance AesonDefaultValue Text where defaultValue = Nothing
73+instance AesonDefaultValue (Maybe a) where defaultValue = Just Nothing
74+instance AesonDefaultValue [a] where defaultValue = Just []
75+instance AesonDefaultValue (Set.Set a) where defaultValue = Just Set.empty
76+instance AesonDefaultValue (InsOrd.InsOrdHashMap k v) where defaultValue = Just InsOrd.empty
77+
78+-------------------------------------------------------------------------------
79+-- ToJSON
80+-------------------------------------------------------------------------------
81+
5282-- | Generic serialisation for swagger records.
5383--
5484-- Features
@@ -57,36 +87,154 @@ makeLenses ''SwaggerAesonOptions
5787-- * possible to add fields
5888-- * possible to merge sub-object
5989sopSwaggerGenericToJSON
60− :: forall a xs. (Generic a, HasDatatypeInfo a, All2 ToJSON (Code a), Code a ~ '[xs])
90+ :: forall a xs.
91+ ( Generic a
92+ , HasDatatypeInfo a
93+ , HasSwaggerAesonOptions a
94+ , All2 ToJSON (Code a)
95+ , All2 Eq (Code a)
96+ , Code a ~ '[xs]
97+ )
98+ => a
99+ -> Value
100+sopSwaggerGenericToJSON x =
101+ let ps = sopSwaggerGenericToJSON' opts (from x) (datatypeInfo proxy) (aesonDefaults proxy)
102+ in object (opts ^. saoAdditionalPairs ++ ps)
103+ where
104+ proxy = Proxy :: Proxy a
105+ opts = swaggerAesonOptions proxy
106+
107+-- | *TODO:* This is only used by ToJSON (ParamSchema SwaggerKindSchema)
108+--
109+-- Also uses default `aesonDefaults`
110+sopSwaggerGenericToJSONWithOpts
111+ :: forall a xs.
112+ ( Generic a
113+ , All2 AesonDefaultValue (Code a)
114+ , HasDatatypeInfo a
115+ , All2 ToJSON (Code a)
116+ , All2 Eq (Code a)
117+ , Code a ~ '[xs]
118+ )
61119 => SwaggerAesonOptions
62120 -> a
63121 -> Value
64−sopSwaggerGenericToJSON opts x =
65− let ps = sopSwaggerGenericToJSON' opts (from x) (datatypeInfo (Proxy :: Proxy a))
122+sopSwaggerGenericToJSONWithOpts opts x =
123+ let ps = sopSwaggerGenericToJSON' opts (from x) (datatypeInfo proxy) defs
66124 in object (opts ^. saoAdditionalPairs ++ ps)
125+ where
126+ proxy = Proxy :: Proxy a
127+ defs = hcpure (Proxy :: Proxy AesonDefaultValue) defaultValue
67128
68−sopSwaggerGenericToJSON' :: All2 ToJSON '[xs] => SwaggerAesonOptions -> SOP I '[xs] -> DatatypeInfo '[xs] -> [(Text, Value)]
69−sopSwaggerGenericToJSON' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil)) =
70− sopSwaggerGenericToJSON'' opts fields fieldsInfo
129+sopSwaggerGenericToJSON'
130+ :: (All2 ToJSON '[xs], All2 Eq '[xs])
131+ => SwaggerAesonOptions
132+ -> SOP I '[xs]
133+ -> DatatypeInfo '[xs]
134+ -> POP Maybe '[xs]
135+ -> [(Text, Value)]
136+sopSwaggerGenericToJSON' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil)) (POP (defs :* Nil)) =
137+ sopSwaggerGenericToJSON'' opts fields fieldsInfo defs
71138
72−sopSwaggerGenericToJSON'' :: All ToJSON xs => SwaggerAesonOptions -> NP I xs -> NP FieldInfo xs -> [(Text, Value)]
139+sopSwaggerGenericToJSON''
140+ :: (All ToJSON xs, All Eq xs)
141+ => SwaggerAesonOptions
142+ -> NP I xs
143+ -> NP FieldInfo xs
144+ -> NP Maybe xs
145+ -> [(Text, Value)]
73146sopSwaggerGenericToJSON'' (SwaggerAesonOptions prefix _ sub) = go
74147 where
75− go :: All ToJSON ys => NP I ys -> NP FieldInfo ys -> [(Text, Value)]
76− go Nil Nil = []
77− go (I x :* xs) (FieldInfo name :* names)
148+ go :: (All ToJSON ys, All Eq ys) => NP I ys -> NP FieldInfo ys -> NP Maybe ys -> [(Text, Value)]
149+ go Nil Nil Nil = []
150+ go (I x :* xs) (FieldInfo name :* names) (def :* defs)
78151 | Just name' == sub = case json of
79152 Object m -> HM.toList m ++ rest
80153 Null -> rest
81154 _ -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show json
82− | json == Null || json == Array mempty || json == Object mempty =
155+ -- If default value: omit it.
156+ | Just x == def =
83157 rest
84158 | otherwise =
85159 (T.pack name', json) : rest
86160 where
87161 json = toJSON x
88162 name' = fieldNameModifier name
89− rest = go xs names
163+ rest = go xs names defs
164+
165+ fieldNameModifier = modifier . drop 1
166+ modifier = lowerFirstUppers . drop (length prefix)
167+ lowerFirstUppers s = map toLower x ++ y
168+ where (x, y) = span isUpper s
169+
170+-------------------------------------------------------------------------------
171+-- FromJSON
172+-------------------------------------------------------------------------------
173+
174+sopSwaggerGenericParseJSON
175+ :: forall a xs.
176+ ( Generic a
177+ , HasDatatypeInfo a
178+ , HasSwaggerAesonOptions a
179+ , All2 FromJSON (Code a)
180+ , All2 Eq (Code a)
181+ , Code a ~ '[xs]
182+ )
183+ => Value
184+ -> Parser a
185+sopSwaggerGenericParseJSON = withObject "Swagger Record Object" $ \obj ->
186+ let ps = sopSwaggerGenericParseJSON' opts obj (datatypeInfo proxy) (aesonDefaults proxy)
187+ in do
188+ traverse (parseAdditionalField obj) (opts ^. saoAdditionalPairs)
189+ to <$> ps
190+ where
191+ proxy = Proxy :: Proxy a
192+ opts = swaggerAesonOptions proxy
193+
194+ parseAdditionalField :: Object -> (Text, Value) -> Parser ()
195+ parseAdditionalField obj (k, v) = do
196+ v' <- obj .: k
197+ unless (v == v') $ fail $
198+ "Additonal field don't match for key " ++ T.unpack k
199+ ++ ": " ++ show v
200+ ++ " /= " ++ show v'
201+
202+sopSwaggerGenericParseJSON'
203+ :: (All2 FromJSON '[xs], All2 Eq '[xs])
204+ => SwaggerAesonOptions
205+ -> Object
206+ -> DatatypeInfo '[xs]
207+ -> POP Maybe '[xs]
208+ -> Parser (SOP I '[xs])
209+sopSwaggerGenericParseJSON' opts obj (ADT _ _ (Record _ fieldsInfo :* Nil)) (POP (defs :* Nil)) =
210+ SOP . Z <$> sopSwaggerGenericParseJSON'' opts obj fieldsInfo defs
211+
212+sopSwaggerGenericParseJSON''
213+ :: (All FromJSON xs, All Eq xs)
214+ => SwaggerAesonOptions
215+ -> Object
216+ -> NP FieldInfo xs
217+ -> NP Maybe xs
218+ -> Parser (NP I xs)
219+sopSwaggerGenericParseJSON'' (SwaggerAesonOptions prefix _ sub) obj = go
220+ where
221+ go :: (All FromJSON ys, All Eq ys) => NP FieldInfo ys -> NP Maybe ys -> Parser (NP I ys)
222+ go Nil Nil = pure Nil
223+ go (FieldInfo name :* names) (def :* defs)
224+ | Just name' == sub =
225+ -- Note: we might strip fields of outer structure.
226+ cons <$> (withDef $ parseJSON $ Object obj) <*> rest
227+ | otherwise = case def of
228+ Just def' -> cons <$> obj .:? T.pack name' .!= def' <*> rest
229+ Nothing -> cons <$> obj .: T.pack name' <*> rest
230+ where
231+ cons h t = I h :* t
232+ name' = fieldNameModifier name
233+ rest = go names defs
234+
235+ withDef = case def of
236+ Just def' -> (<|> pure def')
237+ Nothing -> id
90238
91239 fieldNameModifier = modifier . drop 1
92240 modifier = lowerFirstUppers . drop (length prefix)
src/Data/Swagger/Internal/Schema.hs+2−1
@@ -3,6 +3,7 @@
33{-# LANGUAGE FlexibleContexts #-}
44{-# LANGUAGE FlexibleInstances #-}
55{-# LANGUAGE KindSignatures #-}
6+{-# LANGUAGE DataKinds #-}
67{-# LANGUAGE OverloadedLists #-}
78{-# LANGUAGE OverloadedStrings #-}
89{-# LANGUAGE PackageImports #-}
@@ -615,7 +616,7 @@ gdeclareSchemaRef opts proxy = do
615616 return $ Ref (Reference name)
616617 _ -> Inline <$> gdeclareSchema opts proxy
617618
618−appendItem :: Referenced Schema -> Maybe (SwaggerItems Schema) -> Maybe (SwaggerItems Schema)
619+appendItem :: Referenced Schema -> Maybe (SwaggerItems SwaggerKindSchema) -> Maybe (SwaggerItems SwaggerKindSchema)
619620appendItem x Nothing = Just (SwaggerItemsArray [x])
620621appendItem x (Just (SwaggerItemsArray xs)) = Just (SwaggerItemsArray (xs ++ [x]))
621622appendItem _ _ = error "GToSchema.appendItem: cannot append to SwaggerItemsObject"
src/Data/Swagger/Internal/Utils.hs−31
@@ -55,17 +55,6 @@ gunfoldEnum tname xs _k z c = case lookup (constrIndex c) (zip [1..] xs) of
5555 Just x -> z x
5656 Nothing -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type " ++ tname ++ "."
5757
58−hashMapMapKeys :: (Eq k', Hashable k') => (k -> k') -> HashMap k v -> HashMap k' v
59−hashMapMapKeys f = HashMap.fromList . map (first f) . HashMap.toList
60−
61−hashMapTraverseKeys :: (Eq k', Hashable k', Applicative f) => (k -> f k') -> HashMap k v -> f (HashMap k' v)
62−hashMapTraverseKeys f = fmap HashMap.fromList . traverse g . HashMap.toList
63− where
64− g (x, y) = (\a -> (a, y)) <$> f x
65−
66−hashMapReadKeys :: (Eq k, Read k, Hashable k, Alternative f) => HashMap String v -> f (HashMap k v)
67−hashMapReadKeys = hashMapTraverseKeys (maybe empty pure . readMaybe)
68−
6958jsonPrefix :: String -> Options
7059jsonPrefix prefix = defaultOptions
7160 { fieldLabelModifier = modifier . drop 1
@@ -87,29 +76,10 @@ parseOneOf xs js =
8776 where
8877 ys = zip (map toJSON xs) xs
8978
90−{-# DEPRECATED omitEmpties "will be removed" #-}
91−omitEmpties :: Value -> Value
92−omitEmpties (Object o) = Object (HashMap.filter nonEmpty o)
93− where
94− nonEmpty js = (js /= Object mempty) && (js /= Array mempty) && (js /= Null)
95−omitEmpties js = js
96−
97−genericParseJSONWithSub :: (Generic a, GFromJSON (Rep a)) => Text -> Options -> Value -> Parser a
98−genericParseJSONWithSub sub opts js@(Object o)
99− = genericParseJSON opts js -- try without subjson
100− <|> genericParseJSON opts js' -- try with subjson
101− where
102− js' = Object (HashMap.insert sub (Object o) o)
103−genericParseJSONWithSub _ _ _ = fail "genericParseJSONWithSub: given json is not an object"
104−
10579(<+>) :: Value -> Value -> Value
10680Object x <+> Object y = Object (x <> y)
10781_ <+> _ = error "<+>: merging non-objects"
10882
109−withDefaults :: (Value -> Parser a) -> [Pair] -> Value -> Parser a
110−withDefaults parser defs js@(Object _) = parser (js <+> object defs)
111−withDefaults _ _ _ = empty
112−
11383genericMempty :: (Generic a, GMonoid (Rep a)) => a
11484genericMempty = to gmempty
11585
@@ -165,4 +135,3 @@ instance SwaggerMonoid (Maybe a) where
165135 swaggerMempty = Nothing
166136 swaggerMappend x Nothing = x
167137 swaggerMappend _ y = y
168−
src/Data/Swagger/Lens.hs+8−7
@@ -7,6 +7,7 @@
77{-# LANGUAGE RankNTypes #-}
88{-# LANGUAGE TemplateHaskell #-}
99{-# LANGUAGE TypeFamilies #-}
10+{-# LANGUAGE DataKinds #-}
1011{-# LANGUAGE UndecidableInstances #-}
1112{-# OPTIONS_GHC -fno-warn-orphans #-}
1213#include "overlapping-compat.h"
@@ -59,14 +60,14 @@ makePrisms ''Referenced
5960
6061-- ** 'SwaggerItems' prisms
6162
62−_SwaggerItemsArray :: forall t. (t ~ Schema) => Review (SwaggerItems t) [Referenced Schema]
63+_SwaggerItemsArray :: Review (SwaggerItems SwaggerKindSchema) [Referenced Schema]
6364_SwaggerItemsArray
6465 = prism (\x -> SwaggerItemsArray x) $ \x -> case x of
6566 SwaggerItemsPrimitive c p -> Left (SwaggerItemsPrimitive c p)
6667 SwaggerItemsObject o -> Left (SwaggerItemsObject o)
6768 SwaggerItemsArray a -> Right a
6869
69−_SwaggerItemsObject :: forall t. (t ~ Schema) => Review (SwaggerItems t) (Referenced Schema)
70+_SwaggerItemsObject :: Review (SwaggerItems SwaggerKindSchema) (Referenced Schema)
7071_SwaggerItemsObject
7172 = prism (\x -> SwaggerItemsObject x) $ \x -> case x of
7273 SwaggerItemsPrimitive c p -> Left (SwaggerItemsPrimitive c p)
@@ -91,13 +92,13 @@ instance At Responses where at n = responses . at n
9192instance Ixed Operation where ix n = responses . ix n
9293instance At Operation where at n = responses . at n
9394
94−instance HasParamSchema NamedSchema (ParamSchema Schema) where paramSchema = schema.paramSchema
95+instance HasParamSchema NamedSchema (ParamSchema SwaggerKindSchema) where paramSchema = schema.paramSchema
9596
9697-- HasType instances
97−instance HasType Header (SwaggerType Header) where type_ = paramSchema.type_
98−instance HasType Schema (SwaggerType Schema) where type_ = paramSchema.type_
99−instance HasType NamedSchema (SwaggerType Schema) where type_ = paramSchema.type_
100−instance HasType ParamOtherSchema (SwaggerType ParamOtherSchema) where type_ = paramSchema.type_
98+instance HasType Header (SwaggerType (SwaggerKindNormal Header)) where type_ = paramSchema.type_
99+instance HasType Schema (SwaggerType SwaggerKindSchema) where type_ = paramSchema.type_
100+instance HasType NamedSchema (SwaggerType SwaggerKindSchema) where type_ = paramSchema.type_
101+instance HasType ParamOtherSchema (SwaggerType SwaggerKindParamOtherSchema) where type_ = paramSchema.type_
101102
102103-- HasDefault instances
103104instance HasDefault Header (Maybe Value) where default_ = paramSchema.default_
swagger2.cabal−1
@@ -45,7 +45,6 @@ library
4545 , containers
4646 , hashable
4747 , generics-sop >=0.2 && <0.3
48− , generics-sop-lens >=0.1.0.0 && <0.2
4948 , http-media
5049 , insert-ordered-containers >=0.1.0.0 && <0.2
5150 , lens
test/Data/Swagger/ParamSchemaSpec.hs+3−1
@@ -1,4 +1,5 @@
11{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE DataKinds #-}
23{-# LANGUAGE ScopedTypeVariables #-}
34{-# LANGUAGE TemplateHaskell #-}
45{-# LANGUAGE QuasiQuotes #-}
@@ -11,12 +12,13 @@ import Data.Proxy
1112import GHC.Generics
1213
1314import Data.Swagger
15+import Data.Swagger.Internal (SwaggerKind(..))
1416
1517import SpecCommon
1618import Test.Hspec
1719
1820checkToParamSchema :: ToParamSchema a => Proxy a -> Value -> Spec
19−checkToParamSchema proxy js = (toParamSchema proxy :: ParamSchema Param) <=> js
21+checkToParamSchema proxy js = (toParamSchema proxy :: ParamSchema (SwaggerKindNormal Param)) <=> js
2022
2123spec :: Spec
2224spec = do