@@ -135,7 +135,7 @@ rename name (NamedSchema _ schema) = NamedSchema name schema
135135--
136136-- instance ToSchema Coord
137137-- @
138−class ToSchema a where
138+class Typeable a => ToSchema a where
139139 -- | Convert a type into an optionally named schema
140140 -- together with all used definitions.
141141 -- Note that the schema itself is included in definitions
@@ -610,7 +610,7 @@ instance ToSchema Scientific where declareNamedSchema = plain . paramSchemaToSc
610610instance ToSchema Double where declareNamedSchema = plain . paramSchemaToSchema
611611instance ToSchema Float where declareNamedSchema = plain . paramSchemaToSchema
612612
613−instance HasResolution a => ToSchema (Fixed a) where declareNamedSchema = plain . paramSchemaToSchema
613+instance (Typeable (Fixed a), HasResolution a) => ToSchema (Fixed a) where declareNamedSchema = plain . paramSchemaToSchema
614614
615615instance ToSchema a => ToSchema (Maybe a) where
616616 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy a)
@@ -627,12 +627,18 @@ instance ToSchema UUID.UUID where
627627 declareNamedSchema p = pure $ named "UUID" $ paramSchemaToSchema p
628628 & example ?~ toJSON (UUID.toText UUID.nil)
629629
630−instance (ToSchema a, ToSchema b) => ToSchema (a, b)
631−instance (ToSchema a, ToSchema b, ToSchema c) => ToSchema (a, b, c)
632−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d) => ToSchema (a, b, c, d)
633−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e) => ToSchema (a, b, c, d, e)
634−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f) => ToSchema (a, b, c, d, e, f)
635−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f, ToSchema g) => ToSchema (a, b, c, d, e, f, g)
630+instance (ToSchema a, ToSchema b) => ToSchema (a, b) where
631+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
632+instance (ToSchema a, ToSchema b, ToSchema c) => ToSchema (a, b, c) where
633+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
634+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d) => ToSchema (a, b, c, d) where
635+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
636+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e) => ToSchema (a, b, c, d, e) where
637+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
638+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f) => ToSchema (a, b, c, d, e, f) where
639+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
640+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f, ToSchema g) => ToSchema (a, b, c, d, e, f, g) where
641+ declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
636642
637643timeSchema :: T.Text -> Schema
638644timeSchema fmt = mempty
@@ -683,7 +689,7 @@ instance ToSchemaByteStringError BSL.ByteString => ToSchema BSL.ByteString where
683689instance ToSchema IntSet where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Set Int))
684690
685691-- | NOTE: This schema does not account for the uniqueness of keys.
686−instance ToSchema a => ToSchema (IntMap a) where
692+instance (ToSchema a) => ToSchema (IntMap a) where
687693 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [(Int, a)])
688694
689695instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (Map k v) where
@@ -853,7 +859,7 @@ toSchemaBoundedEnumKeyMapping :: forall map key value.
853859toSchemaBoundedEnumKeyMapping = flip evalDeclare mempty . declareSchemaBoundedEnumKeyMapping
854860
855861-- | A configurable generic @'Schema'@ creator.
856−genericDeclareSchema :: (Generic a, GToSchema (Rep a)) =>
862+genericDeclareSchema :: (Generic a, GToSchema (Rep a), Typeable a) =>
857863 SchemaOptions -> Proxy a -> Declare (Definitions Schema) Schema
858864genericDeclareSchema opts proxy = _namedSchemaSchema <$> genericDeclareNamedSchema opts proxy
859865
@@ -861,9 +867,24 @@ genericDeclareSchema opts proxy = _namedSchemaSchema <$> genericDeclareNamedSche
861867-- This function applied to @'defaultSchemaOptions'@
862868-- is used as the default for @'declareNamedSchema'@
863869-- when the type is an instance of @'Generic'@.
864−genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a)) =>
870+--
871+-- Default implementation will use the name from 'Typeable' instance, including concrete
872+-- instantioations of type variables.
873+--
874+-- For example:
875+--
876+-- >>> _namedSchemaName $ undeclare $ genericDeclareNamedSchema defaultSchemaOptions (Proxy :: Proxy (Either Int Bool))
877+-- Just "Either_Int_Bool"
878+genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a), Typeable a) =>
865879 SchemaOptions -> Proxy a -> Declare (Definitions Schema) NamedSchema
866−genericDeclareNamedSchema opts _ = gdeclareNamedSchema opts (Proxy :: Proxy (Rep a)) mempty
880+genericDeclareNamedSchema opts _ =
881+ rename (Just $ T.pack name) <$> gdeclareNamedSchema opts (Proxy :: Proxy (Rep a)) mempty
882+ where
883+ unspace ' ' = '_'
884+ unspace x = x
885+ orig = fmap unspace $ show $ typeRep @a
886+ name = datatypeNameModifier opts orig
887+
867888
868889-- | Derive a 'Generic'-based name for a datatype and assign it to a given 'Schema'.
869890genericNameSchema :: forall a d f.
@@ -1089,49 +1110,6 @@ data Proxy2 a b = Proxy2
10891110
10901111data Proxy3 a b c = Proxy3
10911112
1092−-- | This class allows to generate schemas for polymorphic types (of kind @Type -> Type@).
1093−--
1094−-- Intended usage:
1095−--
1096−-- >>> data Foo a = Foo { foo :: a, bar :: Int } deriving (Eq, Show, Generic, ToSchema1)
1097−-- >>> :{
1098−-- instance (ToSchema a, Typeable a) => ToSchema (Foo a) where
1099−-- declareNamedSchema _ = declareNamedSchema @(BySchema1 Foo a) Proxy
1100−-- :}
1101−--
1102−-- >>> toNamedSchema @(Foo Int) Proxy ^. name
1103−-- Just "Foo_Int"
1104−-- >>> toNamedSchema @(Foo Bool) Proxy ^. name
1105−-- Just "Foo_Bool"
1106−-- >>> toNamedSchema @(Foo (Foo T.Text)) Proxy ^. name
1107−-- Just "Foo_(Foo_Text)"
1108−class ToSchema1 (f :: * -> *) where
1109− declareNamedSchema1 :: (Generic (f a), GToSchema (Rep (f a)), ToSchema a) => Proxy f -> Proxy a -> Declare (Definitions Schema) NamedSchema
1110−
1111− -- It would be cleaner to have GToSchema constraint only on default signature and not in the class method
1112− -- above, however sadly GHC does not like it.
1113− default declareNamedSchema1 :: forall a. (ToSchema a, Generic (f a), GToSchema (Rep (f a))) => Proxy f -> Proxy a -> Declare (Definitions Schema) NamedSchema
1114− declareNamedSchema1 _ _ = genericDeclareNamedSchema @(f a) defaultSchemaOptions Proxy
1115−
1116−{- | For GHC 8.6+ it's more convenient to use @DerivingVia@ to derive instances of 'ToSchema'
1117−using 'ToSchema1' instance, like this:
1118−
1119−#if __GLASGOW_HASKELL__ >= 806
1120−>>> data Foo a = Foo { foo :: a, bar :: Int } deriving (Eq, Show, Generic, ToSchema1)
1121−>>> deriving via BySchema1 Foo a instance (ToSchema a, Typeable a) => ToSchema (Foo a)
1122−#else
1123−> data Foo a = Foo { foo :: a, bar :: Int } deriving (Eq, Show, Generic, ToSchema1)
1124−> deriving via BySchema1 Foo a instance (ToSchema a, Typeable a) => ToSchema (Foo a)
1125−#endif
1126−-}
1127−newtype BySchema1 f a = BySchema1 (f a)
1128−
1129−instance (ToSchema1 f, Generic (f a), GToSchema (Rep (f a)), Typeable (f a), ToSchema a) => ToSchema (BySchema1 f a) where
1130− declareNamedSchema _ = do
1131− sch <- declareNamedSchema1 @f @a Proxy Proxy
1132− let tName = T.replace " " "_" $ T.pack $ show $ typeRep @(f a)
1133− return $ rename (Just tName) sch
1134−
11351113{- $setup
11361114>>> import Data.OpenApi
11371115>>> import Data.Aeson (encode)
@@ -1141,7 +1119,4 @@ instance (ToSchema1 f, Generic (f a), GToSchema (Rep (f a)), Typeable (f a), ToS
11411119>>> :set -XDeriveAnyClass
11421120>>> :set -XStandaloneDeriving
11431121>>> :set -XTypeApplications
1144−#if __GLASGOW_HASKELL__ >= 806
1145−>>> :set -XDerivingVia
1146−#endif
11471122-}