Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- unnamed :: Schema -> NamedSchema
- named :: Text -> Schema -> NamedSchema
- plain :: Schema -> Declare (Definitions Schema) NamedSchema
- unname :: NamedSchema -> NamedSchema
- rename :: Maybe Text -> NamedSchema -> NamedSchema
- class Typeable a => ToSchema a where
- declareNamedSchema :: Proxy a -> Declare (Definitions Schema) NamedSchema
- declareSchema :: ToSchema a => Proxy a -> Declare (Definitions Schema) Schema
- toNamedSchema :: ToSchema a => Proxy a -> NamedSchema
- schemaName :: ToSchema a => Proxy a -> Maybe Text
- toSchema :: ToSchema a => Proxy a -> Schema
- toSchemaRef :: ToSchema a => Proxy a -> Referenced Schema
- declareSchemaRef :: ToSchema a => Proxy a -> Declare (Definitions Schema) (Referenced Schema)
- inlineSchemasWhen :: Data s => (Text -> Bool) -> Definitions Schema -> s -> s
- inlineSchemas :: Data s => [Text] -> Definitions Schema -> s -> s
- inlineAllSchemas :: Data s => Definitions Schema -> s -> s
- toInlinedSchema :: ToSchema a => Proxy a -> Schema
- inlineNonRecursiveSchemas :: Data s => Definitions Schema -> s -> s
- sketchSchema :: ToJSON a => a -> Schema
- sketchStrictSchema :: ToJSON a => a -> Schema
- class GToSchema (f :: * -> *) where
- gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema
- timeSchema :: Text -> Schema
- type family ToSchemaByteStringError bs where ...
- toSchemaBoundedIntegral :: forall a. (Bounded a, Integral a) => Proxy a -> Schema
- genericToNamedSchemaBoundedIntegral :: forall a d f. (Bounded a, Integral a, Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> NamedSchema
- genericDeclareNamedSchemaNewtype :: forall a d c s i inner. (Generic a, Datatype d, Rep a ~ D1 d (C1 c (S1 s (K1 i inner)))) => SchemaOptions -> (Proxy inner -> Declare (Definitions Schema) Schema) -> Proxy a -> Declare (Definitions Schema) NamedSchema
- declareSchemaBoundedEnumKeyMapping :: forall map key value. (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value) => Proxy (map key value) -> Declare (Definitions Schema) Schema
- toSchemaBoundedEnumKeyMapping :: forall map key value. (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value) => Proxy (map key value) -> Schema
- genericDeclareSchema :: (Generic a, GToSchema (Rep a), Typeable a) => SchemaOptions -> Proxy a -> Declare (Definitions Schema) Schema
- genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a), Typeable a) => SchemaOptions -> Proxy a -> Declare (Definitions Schema) NamedSchema
- genericNameSchema :: forall a d f. (Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> Schema -> NamedSchema
- gdatatypeSchemaName :: forall d. Datatype d => SchemaOptions -> Proxy d -> Maybe Text
- paramSchemaToNamedSchema :: (ToParamSchema a, Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> NamedSchema
- paramSchemaToSchema :: ToParamSchema a => Proxy a -> Schema
- nullarySchema :: Schema
- gtoNamedSchema :: GToSchema f => SchemaOptions -> Proxy f -> NamedSchema
- gdeclareSchema :: GToSchema f => SchemaOptions -> Proxy f -> Declare (Definitions Schema) Schema
- gdeclareSchemaRef :: GToSchema a => SchemaOptions -> Proxy a -> Declare (Definitions Schema) (Referenced Schema)
- appendItem :: Referenced Schema -> Maybe OpenApiItems -> Maybe OpenApiItems
- withFieldSchema :: forall proxy s f. (Selector s, GToSchema f) => SchemaOptions -> proxy s f -> Bool -> Schema -> Declare (Definitions Schema) Schema
- gdeclareNamedSumSchema :: GSumToSchema f => SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema
- type AllNullary = All
- class GSumToSchema (f :: * -> *) where
- gsumToSchema :: SchemaOptions -> Proxy f -> WriterT AllNullary (Declare (Definitions Schema)) [(Text, Referenced Schema)]
- gsumConToSchemaWith :: forall c f. (GToSchema (C1 c f), Constructor c) => Maybe (Referenced Schema) -> SchemaOptions -> Proxy (C1 c f) -> (Text, Referenced Schema)
- gsumConToSchema :: (GToSchema (C1 c f), Constructor c) => SchemaOptions -> Proxy (C1 c f) -> Declare (Definitions Schema) [(Text, Referenced Schema)]
- data Proxy2 a b = Proxy2
- data Proxy3 a b c = Proxy3
Documentation
unnamed :: Schema -> NamedSchema Source #
plain :: Schema -> Declare (Definitions Schema) NamedSchema Source #
unname :: NamedSchema -> NamedSchema Source #
rename :: Maybe Text -> NamedSchema -> NamedSchema Source #
>>>
import Data.Aeson.Types (toJSONKeyText)
>>>
import qualified Data.ByteString.Lazy.Char8 as BSL
>>>
import Data.OpenApi.Internal
>>>
import Data.OpenApi.Internal.Utils (encodePretty)
>>>
import Data.OpenApi.Lens (name, schema)
class Typeable a => ToSchema a where Source #
Convert a type into
.Schema
An example type and instance:
{-# LANGUAGE OverloadedStrings #-} -- allows to writeText
literals {-# LANGUAGE OverloadedLists #-} -- allows to writeMap
andHashMap
as lists import Control.Lens import Data.Proxy import Data.OpenApi data Coord = Coord { x :: Double, y :: Double } instance ToSchema Coord where declareNamedSchema _ = do doubleSchema <- declareSchemaRef (Proxy :: Proxy Double) return $ NamedSchema (Just "Coord") $ mempty & type_ ?~ OpenApiObject & properties .~ [ ("x", doubleSchema) , ("y", doubleSchema) ] & required .~ [ "x", "y" ]
Instead of manually writing your
instance you can
use a default generic implementation of ToSchema
.declareNamedSchema
To do that, simply add deriving
clause to your datatype
and declare a Generic
instance for your datatype without
giving definition for ToSchema
.declareNamedSchema
For instance, the previous example can be simplified into this:
{-# LANGUAGE DeriveGeneric #-} import GHC.Generics (Generic) data Coord = Coord { x :: Double, y :: Double } deriving Generic instance ToSchema Coord
Nothing
declareNamedSchema :: Proxy a -> Declare (Definitions Schema) NamedSchema Source #
Convert a type into an optionally named schema together with all used definitions. Note that the schema itself is included in definitions only if it is recursive (and thus needs its definition in scope).
default declareNamedSchema :: (Generic a, GToSchema (Rep a)) => Proxy a -> Declare (Definitions Schema) NamedSchema Source #
Instances
declareSchema :: ToSchema a => Proxy a -> Declare (Definitions Schema) Schema Source #
Convert a type into a schema and declare all used schema definitions.
toNamedSchema :: ToSchema a => Proxy a -> NamedSchema Source #
Convert a type into an optionally named schema.
>>>
toNamedSchema (Proxy :: Proxy String) ^. name
Nothing>>>
BSL.putStrLn $ encodePretty (toNamedSchema (Proxy :: Proxy String) ^. schema)
{ "type": "string" }
>>>
toNamedSchema (Proxy :: Proxy Day) ^. name
Just "Day">>>
BSL.putStrLn $ encodePretty (toNamedSchema (Proxy :: Proxy Day) ^. schema)
{ "example": "2016-07-22", "format": "date", "type": "string" }
schemaName :: ToSchema a => Proxy a -> Maybe Text Source #
Get type's schema name according to its
instance.ToSchema
>>>
schemaName (Proxy :: Proxy Int)
Nothing
>>>
schemaName (Proxy :: Proxy UTCTime)
Just "UTCTime"
toSchema :: ToSchema a => Proxy a -> Schema Source #
Convert a type into a schema.
>>>
BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy Int8)
{ "maximum": 127, "minimum": -128, "type": "integer" }
>>>
BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy [Day])
{ "items": { "$ref": "#/components/schemas/Day" }, "type": "array" }
toSchemaRef :: ToSchema a => Proxy a -> Referenced Schema Source #
Convert a type into a referenced schema if possible. Only named schemas can be referenced, nameless schemas are inlined.
>>>
BSL.putStrLn $ encodePretty $ toSchemaRef (Proxy :: Proxy Integer)
{ "type": "integer" }
>>>
BSL.putStrLn $ encodePretty $ toSchemaRef (Proxy :: Proxy Day)
{ "$ref": "#/components/schemas/Day" }
declareSchemaRef :: ToSchema a => Proxy a -> Declare (Definitions Schema) (Referenced Schema) Source #
Convert a type into a referenced schema if possible and declare all used schema definitions. Only named schemas can be referenced, nameless schemas are inlined.
Schema definitions are typically declared for every referenced schema.
If
returns a reference, a corresponding schema
will be declared (regardless of whether it is recusive or not).declareSchemaRef
inlineSchemasWhen :: Data s => (Text -> Bool) -> Definitions Schema -> s -> s Source #
Inline any referenced schema if its name satisfies given predicate.
NOTE: if a referenced schema is not found in definitions the predicate is ignored and schema stays referenced.
WARNING:
will produce infinite schemas
when inlining recursive schemas.inlineSchemasWhen
inlineSchemas :: Data s => [Text] -> Definitions Schema -> s -> s Source #
Inline any referenced schema if its name is in the given list.
NOTE: if a referenced schema is not found in definitions it stays referenced even if it appears in the list of names.
WARNING:
will produce infinite schemas
when inlining recursive schemas.inlineSchemas
inlineAllSchemas :: Data s => Definitions Schema -> s -> s Source #
Inline all schema references for which the definition
can be found in
.Definitions
WARNING:
will produce infinite schemas
when inlining recursive schemas.inlineAllSchemas
toInlinedSchema :: ToSchema a => Proxy a -> Schema Source #
Convert a type into a schema without references.
>>>
BSL.putStrLn $ encodePretty $ toInlinedSchema (Proxy :: Proxy [Day])
{ "items": { "example": "2016-07-22", "format": "date", "type": "string" }, "type": "array" }
WARNING:
will produce infinite schema
when inlining recursive schemas.toInlinedSchema
inlineNonRecursiveSchemas :: Data s => Definitions Schema -> s -> s Source #
Inline all non-recursive schemas for which the definition
can be found in
.Definitions
sketchSchema :: ToJSON a => a -> Schema Source #
Make an unrestrictive sketch of a
based on a Schema
instance.
Produced schema can be used for further refinement.ToJSON
>>>
BSL.putStrLn $ encodePretty $ sketchSchema "hello"
{ "example": "hello", "type": "string" }
>>>
BSL.putStrLn $ encodePretty $ sketchSchema (1, 2, 3)
{ "example": [ 1, 2, 3 ], "items": { "type": "number" }, "type": "array" }
>>>
BSL.putStrLn $ encodePretty $ sketchSchema ("Jack", 25)
{ "example": [ "Jack", 25 ], "items": [ { "type": "string" }, { "type": "number" } ], "type": "array" }
>>>
data Person = Person { name :: String, age :: Int } deriving (Generic)
>>>
instance ToJSON Person
>>>
BSL.putStrLn $ encodePretty $ sketchSchema (Person "Jack" 25)
{ "example": { "age": 25, "name": "Jack" }, "properties": { "age": { "type": "number" }, "name": { "type": "string" } }, "required": [ "age", "name" ], "type": "object" }
sketchStrictSchema :: ToJSON a => a -> Schema Source #
Make a restrictive sketch of a
based on a Schema
instance.
Produced schema uses as much constraints as possible.ToJSON
>>>
BSL.putStrLn $ encodePretty $ sketchStrictSchema "hello"
{ "enum": [ "hello" ], "maxLength": 5, "minLength": 5, "pattern": "hello", "type": "string" }
>>>
BSL.putStrLn $ encodePretty $ sketchStrictSchema (1, 2, 3)
{ "enum": [ [ 1, 2, 3 ] ], "items": [ { "enum": [ 1 ], "maximum": 1, "minimum": 1, "multipleOf": 1, "type": "number" }, { "enum": [ 2 ], "maximum": 2, "minimum": 2, "multipleOf": 2, "type": "number" }, { "enum": [ 3 ], "maximum": 3, "minimum": 3, "multipleOf": 3, "type": "number" } ], "maxItems": 3, "minItems": 3, "type": "array", "uniqueItems": true }
>>>
BSL.putStrLn $ encodePretty $ sketchStrictSchema ("Jack", 25)
{ "enum": [ [ "Jack", 25 ] ], "items": [ { "enum": [ "Jack" ], "maxLength": 4, "minLength": 4, "pattern": "Jack", "type": "string" }, { "enum": [ 25 ], "maximum": 25, "minimum": 25, "multipleOf": 25, "type": "number" } ], "maxItems": 2, "minItems": 2, "type": "array", "uniqueItems": true }
>>>
data Person = Person { name :: String, age :: Int } deriving (Generic)
>>>
instance ToJSON Person
>>>
BSL.putStrLn $ encodePretty $ sketchStrictSchema (Person "Jack" 25)
{ "enum": [ { "age": 25, "name": "Jack" } ], "maxProperties": 2, "minProperties": 2, "properties": { "age": { "enum": [ 25 ], "maximum": 25, "minimum": 25, "multipleOf": 25, "type": "number" }, "name": { "enum": [ "Jack" ], "maxLength": 4, "minLength": 4, "pattern": "Jack", "type": "string" } }, "required": [ "age", "name" ], "type": "object" }
class GToSchema (f :: * -> *) where Source #
gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema Source #
Instances
timeSchema :: Text -> Schema Source #
type family ToSchemaByteStringError bs where ... Source #
genericToNamedSchemaBoundedIntegral :: forall a d f. (Bounded a, Integral a, Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> NamedSchema Source #
genericDeclareNamedSchemaNewtype Source #
:: forall a d c s i inner. (Generic a, Datatype d, Rep a ~ D1 d (C1 c (S1 s (K1 i inner)))) | |
=> SchemaOptions | How to derive the name. |
-> (Proxy inner -> Declare (Definitions Schema) Schema) | How to create a schema for the wrapped type. |
-> Proxy a | |
-> Declare (Definitions Schema) NamedSchema |
Declare a named schema for a newtype
wrapper.
declareSchemaBoundedEnumKeyMapping :: forall map key value. (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value) => Proxy (map key value) -> Declare (Definitions Schema) Schema Source #
Declare Schema
for a mapping with Bounded
Enum
keys.
This makes a much more useful schema when there aren't many options for key values.
>>>
data ButtonState = Neutral | Focus | Active | Hover | Disabled deriving (Show, Bounded, Enum, Generic)
>>>
instance ToJSON ButtonState
>>>
instance ToSchema ButtonState
>>>
instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
>>>
type ImageUrl = T.Text
>>>
BSL.putStrLn $ encodePretty $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
{ "properties": { "Active": { "type": "string" }, "Disabled": { "type": "string" }, "Focus": { "type": "string" }, "Hover": { "type": "string" }, "Neutral": { "type": "string" } }, "type": "object" }
Note: this is only useful when key
is encoded with ToJSONKeyText
.
If it is encoded with ToJSONKeyValue
then a regular schema for [(key, value)]
is used.
toSchemaBoundedEnumKeyMapping :: forall map key value. (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value) => Proxy (map key value) -> Schema Source #
A Schema
for a mapping with Bounded
Enum
keys.
This makes a much more useful schema when there aren't many options for key values.
>>>
data ButtonState = Neutral | Focus | Active | Hover | Disabled deriving (Show, Bounded, Enum, Generic)
>>>
instance ToJSON ButtonState
>>>
instance ToSchema ButtonState
>>>
instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
>>>
type ImageUrl = T.Text
>>>
BSL.putStrLn $ encodePretty $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
{ "properties": { "Active": { "type": "string" }, "Disabled": { "type": "string" }, "Focus": { "type": "string" }, "Hover": { "type": "string" }, "Neutral": { "type": "string" } }, "type": "object" }
Note: this is only useful when key
is encoded with ToJSONKeyText
.
If it is encoded with ToJSONKeyValue
then a regular schema for [(key, value)]
is used.
genericDeclareSchema :: (Generic a, GToSchema (Rep a), Typeable a) => SchemaOptions -> Proxy a -> Declare (Definitions Schema) Schema Source #
A configurable generic
creator.Schema
genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a), Typeable a) => SchemaOptions -> Proxy a -> Declare (Definitions Schema) NamedSchema Source #
A configurable generic
creator.
This function applied to NamedSchema
is used as the default for defaultSchemaOptions
when the type is an instance of declareNamedSchema
.Generic
Default implementation will use the name from Typeable
instance, including concrete
instantioations of type variables.
For example:
>>>
_namedSchemaName $ undeclare $ genericDeclareNamedSchema defaultSchemaOptions (Proxy :: Proxy (Either Int Bool))
Just "Either_Int_Bool"
genericNameSchema :: forall a d f. (Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> Schema -> NamedSchema Source #
gdatatypeSchemaName :: forall d. Datatype d => SchemaOptions -> Proxy d -> Maybe Text Source #
paramSchemaToNamedSchema :: (ToParamSchema a, Generic a, Rep a ~ D1 d f, Datatype d) => SchemaOptions -> Proxy a -> NamedSchema Source #
Construct NamedSchema
usinng ToParamSchema
.
paramSchemaToSchema :: ToParamSchema a => Proxy a -> Schema Source #
Construct Schema
usinng ToParamSchema
.
gtoNamedSchema :: GToSchema f => SchemaOptions -> Proxy f -> NamedSchema Source #
gdeclareSchema :: GToSchema f => SchemaOptions -> Proxy f -> Declare (Definitions Schema) Schema Source #
gdeclareSchemaRef :: GToSchema a => SchemaOptions -> Proxy a -> Declare (Definitions Schema) (Referenced Schema) Source #
appendItem :: Referenced Schema -> Maybe OpenApiItems -> Maybe OpenApiItems Source #
withFieldSchema :: forall proxy s f. (Selector s, GToSchema f) => SchemaOptions -> proxy s f -> Bool -> Schema -> Declare (Definitions Schema) Schema Source #
gdeclareNamedSumSchema :: GSumToSchema f => SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema Source #
type AllNullary = All Source #
class GSumToSchema (f :: * -> *) where Source #
gsumToSchema :: SchemaOptions -> Proxy f -> WriterT AllNullary (Declare (Definitions Schema)) [(Text, Referenced Schema)] Source #
Instances
gsumConToSchemaWith :: forall c f. (GToSchema (C1 c f), Constructor c) => Maybe (Referenced Schema) -> SchemaOptions -> Proxy (C1 c f) -> (Text, Referenced Schema) Source #
Convert one component of the sum to schema, to be later combined with oneOf
.
gsumConToSchema :: (GToSchema (C1 c f), Constructor c) => SchemaOptions -> Proxy (C1 c f) -> Declare (Definitions Schema) [(Text, Referenced Schema)] Source #
>>>
import Data.OpenApi
>>>
import Data.Aeson (encode)
>>>
import Data.Aeson.Types (toJSONKeyText)
>>>
import Data.OpenApi.Internal.Utils
>>>
:set -XScopedTypeVariables
>>>
:set -XDeriveAnyClass
>>>
:set -XStandaloneDeriving
>>>
:set -XTypeApplications