{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | This module specifies the data types from the OpenAPI specification 3.0.3 Schema -- -- For more information see http://spec.openapis.org/oas/v3.0.3 -- and https://json-schema.org/ -- -- All names in this module correspond to the respective OpenAPI types module OpenAPI.Generate.Types.Schema where import qualified Data.Map as Map import qualified Data.Scientific as Scientific import Data.Set as Set import qualified Data.Text as T import Data.Text (Text) import Data.Yaml import GHC.Generics import OpenAPI.Generate.Types.ExternalDocumentation import OpenAPI.Generate.Types.Referencable type Schema = Referencable SchemaObject data SchemaObject = SchemaObject { type' :: SchemaType, title :: Maybe Text, multipleOf :: Maybe Integer, maximum :: Maybe Float, exclusiveMaximum :: Bool, minimum :: Maybe Float, exclusiveMinimum :: Bool, maxLength :: Maybe Word, minLength :: Maybe Word, pattern' :: Maybe Text, maxItems :: Maybe Word, minItems :: Maybe Word, uniqueItems :: Bool, maxProperties :: Maybe Word, minProperties :: Maybe Word, required :: Set Text, enum :: Set Value, allOf :: Set Schema, oneOf :: Set Schema, anyOf :: Set Schema, not :: Maybe Schema, properties :: Map.Map Text Schema, additionalProperties :: AdditionalProperties, description :: Maybe Text, format :: Maybe Text, -- default would have the same value type as restricted by -- the schema. Stripe only uses Text default values default' :: Maybe ConcreteValue, nullable :: Bool, discriminator :: Maybe DiscriminatorObject, readOnly :: Bool, writeOnly :: Bool, xml :: Maybe XMLObject, externalDocs :: Maybe ExternalDocumentationObject, example :: Maybe Value, deprecated :: Bool, items :: Maybe Schema } deriving (Show, Eq, Ord, Generic) instance FromJSON SchemaObject where parseJSON = withObject "SchemaObject" $ \o -> SchemaObject <$> o .:? "type" .!= SchemaTypeObject <*> o .:? "title" <*> o .:? "multipleOf" <*> o .:? "maximum" <*> o .:? "exclusiveMaximum" .!= False <*> o .:? "minimum" <*> o .:? "exclusiveMinimum" .!= False <*> o .:? "maxLength" <*> o .:? "minLength" <*> o .:? "pattern" <*> o .:? "maxItems" <*> o .:? "minItems" <*> o .:? "uniqueItems" .!= False <*> o .:? "maxProperties" <*> o .:? "minProperties" <*> o .:? "required" .!= Set.empty <*> o .:? "enum" .!= Set.empty <*> o .:? "allOf" .!= Set.empty <*> o .:? "oneOf" .!= Set.empty <*> o .:? "anyOf" .!= Set.empty <*> o .:? "not" <*> o .:? "properties" .!= Map.empty <*> o .:? "additionalProperties" .!= HasAdditionalProperties <*> o .:? "description" <*> o .:? "format" <*> o .:? "default" <*> o .:? "nullable" .!= False <*> o .:? "discriminator" <*> o .:? "readOnly" .!= False <*> o .:? "writeOnly" .!= False <*> o .:? "xml" <*> o .:? "externalDocs" <*> o .:? "example" <*> o .:? "deprecated" .!= False <*> o .:? "items" data SchemaType = SchemaTypeString | SchemaTypeNumber | SchemaTypeInteger | SchemaTypeBool | SchemaTypeObject | SchemaTypeArray deriving (Show, Eq, Ord, Generic) instance FromJSON SchemaType where parseJSON (String "integer") = pure SchemaTypeInteger parseJSON (String "string") = pure SchemaTypeString parseJSON (String "number") = pure SchemaTypeNumber parseJSON (String "boolean") = pure SchemaTypeBool parseJSON (String "array") = pure SchemaTypeArray parseJSON (String "object") = pure SchemaTypeObject parseJSON (String x) = fail $ "Only types integer, string, number, bool, array and object are supported but got: " <> T.unpack x parseJSON _ = fail "type must be of type string" data DiscriminatorObject = DiscriminatorObject { propertyName :: Text, mapping :: Map.Map Text Text } deriving (Show, Eq, Ord, Generic) instance FromJSON DiscriminatorObject where parseJSON = withObject "DiscriminatorObject" $ \o -> DiscriminatorObject <$> o .: "propertyName" <*> o .:? "mapping" .!= Map.empty -- So that Sets are possible instance Ord Value where (Object a) `compare` (Object b) = compare a b (Array a) `compare` (Array b) = compare a b (String a) `compare` (String b) = compare a b (Number a) `compare` (Number b) = compare a b (Bool a) `compare` (Bool b) = compare a b Null `compare` Null = EQ (Object _) `compare` _ = GT _ `compare` (Object _) = LT (Array _) `compare` _ = GT _ `compare` (Array _) = LT (String _) `compare` _ = GT _ `compare` (String _) = LT (Number _) `compare` _ = GT _ `compare` (Number _) = LT (Bool _) `compare` _ = GT _ `compare` (Bool _) = LT data ConcreteValue = StringDefaultValue Text | NumericDefaultValue Scientific.Scientific | BoolDefaultValue Bool | OtherDefaultValue Value deriving (Show, Eq, Ord, Generic) instance FromJSON ConcreteValue where parseJSON v@(String _) = StringDefaultValue <$> parseJSON v parseJSON v@(Number _) = NumericDefaultValue <$> parseJSON v parseJSON v@(Bool _) = BoolDefaultValue <$> parseJSON v parseJSON v = pure $ OtherDefaultValue v data AdditionalProperties = NoAdditionalProperties | HasAdditionalProperties | AdditionalPropertiesWithSchema Schema deriving (Show, Eq, Ord, Generic) instance FromJSON AdditionalProperties where parseJSON (Bool False) = pure NoAdditionalProperties parseJSON (Bool True) = pure HasAdditionalProperties parseJSON v = AdditionalPropertiesWithSchema <$> parseJSON v data XMLObject = XMLObject { name :: Maybe Text, namespace :: Maybe Text, prefix :: Maybe Text, attribute :: Bool, wrapped :: Bool } deriving (Show, Eq, Ord, Generic) instance FromJSON XMLObject where parseJSON = withObject "SchemaObject" $ \o -> XMLObject <$> o .:? "name" <*> o .:? "namespace" <*> o .:? "prefix" <*> o .:? "attribute" .!= False <*> o .:? "wrapped" .!= False