@@ -10,6 +10,7 @@
1010{-# LANGUAGE ScopedTypeVariables #-}
1111{-# LANGUAGE StandaloneDeriving #-}
1212{-# LANGUAGE TemplateHaskell #-}
13+{-# LANGUAGE UndecidableInstances #-}
1314module Data.Swagger.Internal where
1415
1516import Control.Applicative
@@ -324,9 +325,33 @@ data ParamOtherSchema = ParamOtherSchema
324325 -- Default value is csv.
325326 , _paramOtherSchemaCollectionFormat :: Maybe (CollectionFormat Param)
326327
327− , _paramOtherSchemaParamSchema :: ParamSchema ParamOtherSchema Items
328+ , _paramOtherSchemaParamSchema :: ParamSchema ParamOtherSchema
328329 } deriving (Eq, Show, Generic, Data, Typeable)
329330
331+data SwaggerItems t where
332+ SwaggerItemsPrimitive :: Items -> SwaggerItems t
333+ SwaggerItemsObject :: Referenced Schema -> SwaggerItems Schema
334+ SwaggerItemsArray :: [Referenced Schema] -> SwaggerItems Schema
335+
336+deriving instance Eq (SwaggerItems t)
337+deriving instance Show (SwaggerItems t)
338+deriving instance Typeable (SwaggerItems t)
339+
340+swaggerItemsPrimitiveConstr :: Constr
341+swaggerItemsPrimitiveConstr = mkConstr swaggerItemsDataType "SwaggerItemsPrimitive" [] Prefix
342+
343+swaggerItemsDataType :: DataType
344+swaggerItemsDataType = mkDataType "Data.Swagger.SwaggerItems" [swaggerItemsPrimitiveConstr]
345+
346+instance {-# OVERLAPPABLE #-} Typeable t => Data (SwaggerItems t) where
347+ gunfold k z c = case constrIndex c of
348+ 1 -> k (z SwaggerItemsPrimitive)
349+ _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type (SwaggerItems t)."
350+ toConstr _ = swaggerItemsPrimitiveConstr
351+ dataTypeOf _ = swaggerItemsDataType
352+
353+deriving instance Data (SwaggerItems Schema)
354+
330355data SwaggerType t where
331356 SwaggerString :: SwaggerType t
332357 SwaggerNumber :: SwaggerType t
@@ -453,15 +478,10 @@ data Schema = Schema
453478 , _schemaMaxProperties :: Maybe Integer
454479 , _schemaMinProperties :: Maybe Integer
455480
456− , _schemaParamSchema :: ParamSchema Schema SchemaItems
481+ , _schemaParamSchema :: ParamSchema Schema
457482 } deriving (Eq, Show, Generic, Data, Typeable)
458483
459−data SchemaItems
460− = SchemaItemsObject (Referenced Schema)
461− | SchemaItemsArray [Referenced Schema]
462− deriving (Eq, Show, Generic, Data, Typeable)
463−
464−data ParamSchema t items = ParamSchema
484+data ParamSchema t = ParamSchema
465485 { -- | Declares the value of the parameter that the server will use if none is provided,
466486 -- for example a @"count"@ to control the number of results per page might default to @100@
467487 -- if not supplied by the client in the request.
@@ -471,7 +491,7 @@ data ParamSchema t items = ParamSchema
471491
472492 , _paramSchemaType :: SwaggerType t
473493 , _paramSchemaFormat :: Maybe Format
474− , _paramSchemaItems :: Maybe items
494+ , _paramSchemaItems :: Maybe (SwaggerItems t)
475495 , _paramSchemaMaximum :: Maybe Scientific
476496 , _paramSchemaExclusiveMaximum :: Maybe Bool
477497 , _paramSchemaMinimum :: Maybe Scientific
@@ -486,7 +506,7 @@ data ParamSchema t items = ParamSchema
486506 , _paramSchemaMultipleOf :: Maybe Scientific
487507 } deriving (Eq, Show, Generic, Typeable)
488508
489−deriving instance (Data t, Data (SwaggerType t), Data i) => Data (ParamSchema t i)
509+deriving instance (Data t, Data (SwaggerType t), Data (SwaggerItems t)) => Data (ParamSchema t)
490510
491511data Xml = Xml
492512 { -- | Replaces the name of the element/attribute used for the described schema property.
@@ -521,7 +541,7 @@ data Items = Items
521541 -- Default value is @'ItemsCollectionCSV'@.
522542 _itemsCollectionFormat :: Maybe (CollectionFormat Items)
523543
524− , _itemsParamSchema :: ParamSchema Items Items
544+ , _itemsParamSchema :: ParamSchema Items
525545 } deriving (Eq, Show, Generic, Data, Typeable)
526546
527547-- | A container for the expected responses of an operation.
@@ -571,7 +591,7 @@ data Header = Header
571591 -- Default value is @'ItemsCollectionCSV'@.
572592 , _headerCollectionFormat :: Maybe (CollectionFormat Items)
573593
574− , _headerParamSchema :: ParamSchema Header Items
594+ , _headerParamSchema :: ParamSchema Header
575595 } deriving (Eq, Show, Generic, Data, Typeable)
576596
577597data Example = Example { getExample :: Map MediaType Value }
@@ -706,7 +726,7 @@ instance Monoid Schema where
706726 mempty = genericMempty
707727 mappend = genericMappend
708728
709−instance Monoid (ParamSchema t i) where
729+instance Monoid (ParamSchema t) where
710730 mempty = genericMempty
711731 mappend = genericMappend
712732
@@ -742,7 +762,7 @@ instance SwaggerMonoid Info
742762instance SwaggerMonoid Paths
743763instance SwaggerMonoid PathItem
744764instance SwaggerMonoid Schema
745−instance SwaggerMonoid (ParamSchema t i)
765+instance SwaggerMonoid (ParamSchema t)
746766instance SwaggerMonoid Param
747767instance SwaggerMonoid ParamOtherSchema
748768instance SwaggerMonoid Responses
@@ -870,6 +890,11 @@ instance ToJSON Header where
870890instance ToJSON Items where
871891 toJSON = genericToJSONWithSub "paramSchema" (jsonPrefix "items")
872892
893+instance ToJSON (SwaggerItems t) where
894+ toJSON (SwaggerItemsPrimitive x) = toJSON x
895+ toJSON (SwaggerItemsObject x) = toJSON x
896+ toJSON (SwaggerItemsArray x) = toJSON x
897+
873898instance ToJSON Host where
874899 toJSON (Host host mport) = toJSON $
875900 case mport of
@@ -892,10 +917,6 @@ instance ToJSON ParamAnySchema where
892917instance ToJSON ParamOtherSchema where
893918 toJSON = genericToJSONWithSub "paramSchema" (jsonPrefix "paramOtherSchema")
894919
895−instance ToJSON SchemaItems where
896− toJSON (SchemaItemsObject x) = toJSON x
897− toJSON (SchemaItemsArray xs) = toJSON xs
898−
899920instance ToJSON Responses where
900921 toJSON (Responses def rs) = omitEmpties $
901922 toJSON (hashMapMapKeys show rs) <+> object [ "default" .= def ]
@@ -940,7 +961,7 @@ instance ToJSON (CollectionFormat t) where
940961 toJSON CollectionPipes = "pipes"
941962 toJSON CollectionMulti = "multi"
942963
943−instance ToJSON i => ToJSON (ParamSchema t i) where
964+instance ToJSON (ParamSchema t) where
944965 toJSON = genericToJSON (jsonPrefix "paramSchema")
945966
946967-- =======================================================================
@@ -1003,6 +1024,14 @@ instance FromJSON Header where
10031024instance FromJSON Items where
10041025 parseJSON = genericParseJSONWithSub "paramSchema" (jsonPrefix "items")
10051026
1027+instance {-# OVERLAPPABLE #-} FromJSON (SwaggerItems t) where
1028+ parseJSON js = SwaggerItemsPrimitive <$> parseJSON js
1029+
1030+instance {-# OVERLAPPING #-} FromJSON (SwaggerItems Schema) where
1031+ parseJSON js@(Object _) = SwaggerItemsObject <$> parseJSON js
1032+ parseJSON js@(Array _) = SwaggerItemsArray <$> parseJSON js
1033+ parseJSON _ = empty
1034+
10061035instance FromJSON Host where
10071036 parseJSON (String s) =
10081037 case fromInteger <$> readMaybe portStr of
@@ -1035,11 +1064,6 @@ instance FromJSON ParamAnySchema where
10351064instance FromJSON ParamOtherSchema where
10361065 parseJSON = genericParseJSONWithSub "paramSchema" (jsonPrefix "paramOtherSchema")
10371066
1038−instance FromJSON SchemaItems where
1039− parseJSON js@(Object _) = SchemaItemsObject <$> parseJSON js
1040− parseJSON js@(Array _) = SchemaItemsArray <$> parseJSON js
1041− parseJSON _ = empty
1042−
10431067instance FromJSON Responses where
10441068 parseJSON (Object o) = Responses
10451069 <$> o .:? "default"
@@ -1101,8 +1125,10 @@ instance FromJSON (CollectionFormat Param) where
11011125instance FromJSON (CollectionFormat Items) where
11021126 parseJSON = parseOneOf [CollectionCSV, CollectionSSV, CollectionTSV, CollectionPipes]
11031127
1104−-- NOTE: The constraint @FromJSON (SwaggerType t)@ is necessary here!
1128+-- NOTE: The constraints @FromJSON (SwaggerType t)@ and
1129+-- @FromJSON (SwaggerItems t)@ are necessary here!
11051130-- Without the constraint the general instance will be used
1106−-- that only accepts common types (i.e. NOT object, null or file).
1107−instance (FromJSON (SwaggerType t), FromJSON i) => FromJSON (ParamSchema t i) where
1131+-- that only accepts common types (i.e. NOT object, null or file)
1132+-- and primitive array items.
1133+instance (FromJSON (SwaggerType t), FromJSON (SwaggerItems t)) => FromJSON (ParamSchema t) where
11081134 parseJSON = genericParseJSON (jsonPrefix "ParamSchema")