Skip to content

Commit

Permalink
OpenAPI arrays use 'minItems', not 'minLength'
Browse files Browse the repository at this point in the history
  • Loading branch information
ysangkok committed Apr 19, 2024
1 parent 179b6a4 commit 93e7955
Show file tree
Hide file tree
Showing 19 changed files with 333 additions and 80 deletions.
33 changes: 18 additions & 15 deletions json-fleece-codegen-util/src/Fleece/CodeGenUtil.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ module Fleece.CodeGenUtil
, CodeGenUnionMember (..)
, inferSchemaInfoForTypeName
, inferTypeForInputName
, arrayTypeInfo
, arrayLikeTypeInfo
, mapTypeInfo
, nullableTypeInfo
, anyJSONSchemaTypeInfo
Expand Down Expand Up @@ -261,7 +261,7 @@ newtype CodeGenAdditionalProperties = CodeGenAdditionalProperties
data CodeGenRefType
= TypeReference T.Text
| CodeGenRefMap CodeGenRefType
| CodeGenRefArray CodeGenRefType
| CodeGenRefArray (Maybe Integer) CodeGenRefType
| CodeGenRefNullable CodeGenRefType

resolveRefTypeInfo ::
Expand All @@ -278,8 +278,8 @@ resolveRefTypeInfo typeMap =
pure (codeGenTypeSchemaInfo codeGenType)
_ ->
codeGenError $ "Type " <> show ref <> " not found."
CodeGenRefArray itemType ->
fmap arrayTypeInfo (go itemType)
CodeGenRefArray mbMinItems itemType ->
fmap (arrayLikeTypeInfo mbMinItems) (go itemType)
CodeGenRefMap itemType ->
fmap mapTypeInfo (go itemType)
CodeGenRefNullable itemType ->
Expand All @@ -305,7 +305,7 @@ resolveFieldDescription typeMap =
Nothing
Nothing ->
Nothing
CodeGenRefArray itemType ->
CodeGenRefArray _mbMinItems itemType ->
go itemType
CodeGenRefMap itemType ->
go itemType
Expand Down Expand Up @@ -464,6 +464,15 @@ nonEmptyTypeInfo itemInfo =
<> ")"
}

arrayLikeTypeInfo :: Maybe Integer -> SchemaTypeInfo -> SchemaTypeInfo
arrayLikeTypeInfo mbMinItems =
case mbMinItems of
Just minLength
| minLength >= 1 ->
nonEmptyTypeInfo
_ ->
arrayTypeInfo

mapTypeInfo :: SchemaTypeInfo -> SchemaTypeInfo
mapTypeInfo itemInfo =
itemInfo
Expand Down Expand Up @@ -1109,8 +1118,8 @@ generateCodeGenDataFormat typeMap typeName format = do
pure $ generateFleeceEnum typeName values typeOptions
CodeGenObject typeOptions fields mbAdditionalProperties ->
generateFleeceObject typeMap typeName fields mbAdditionalProperties typeOptions
CodeGenArray typeOptions mbMinLength itemType ->
generateFleeceArray typeMap typeName mbMinLength itemType typeOptions
CodeGenArray typeOptions mbMinItems itemType ->
generateFleeceArray typeMap typeName mbMinItems itemType typeOptions
CodeGenUnion members ->
generateFleeceUnion typeMap typeName members

Expand Down Expand Up @@ -1467,15 +1476,9 @@ generateFleeceArray ::
CodeGenRefType ->
TypeOptions ->
CodeGen ([HC.VarName], HC.HaskellCode)
generateFleeceArray typeMap typeName mbMinLength itemType typeOptions = do
generateFleeceArray typeMap typeName mbMinItems itemType typeOptions = do
let
elemTypeInfo =
case mbMinLength of
Just minLength
| minLength >= 1 ->
nonEmptyTypeInfo
_ ->
arrayTypeInfo
elemTypeInfo = arrayLikeTypeInfo mbMinItems
typeInfo <- fmap elemTypeInfo (resolveRefTypeInfo typeMap itemType)
generateFleeceNewtype
typeMap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ nonEmptyOf itemName =
"("
<> typeNameToCodeDefaultQualification nonEmptyType
<> " "
<> itemName
<> guardParens itemName
<> ")"

mapType :: TypeName
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOne
( MinItemsOne(..)
, minItemsOneSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (Eq, Show)
import qualified TestCases.Types.MinItemsOne.MinItemsOneItem as MinItemsOneItem

newtype MinItemsOne = MinItemsOne (NEL.NonEmpty MinItemsOneItem.MinItemsOneItem)
deriving (Show, Eq)

minItemsOneSchema :: FC.Fleece schema => schema MinItemsOne
minItemsOneSchema =
FC.coerceSchema (FC.nonEmpty MinItemsOneItem.minItemsOneItemSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOne.MinItemsOneItem
( MinItemsOneItem(..)
, minItemsOneItemSchema
) where

import qualified Fleece.Core as FC
import Prelude (Bool, Eq, Show)

newtype MinItemsOneItem = MinItemsOneItem Bool
deriving (Show, Eq)

minItemsOneItemSchema :: FC.Fleece schema => schema MinItemsOneItem
minItemsOneItemSchema =
FC.coerceSchema FC.boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInline
( MinItemsOneInline(..)
, minItemsOneInlineSchema
) where

import qualified Data.List.NonEmpty as NEL
import Fleece.Core ((#+))
import qualified Fleece.Core as FC
import Prelude (($), Eq, Maybe, Show)
import qualified TestCases.Types.MinItemsOneInline.SomeArrayItem as SomeArrayItem

data MinItemsOneInline = MinItemsOneInline
{ someArray :: Maybe (NEL.NonEmpty SomeArrayItem.SomeArrayItem)
}
deriving (Eq, Show)

minItemsOneInlineSchema :: FC.Fleece schema => schema MinItemsOneInline
minItemsOneInlineSchema =
FC.object $
FC.constructor MinItemsOneInline
#+ FC.optional "someArray" someArray (FC.nonEmpty SomeArrayItem.someArrayItemSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInline.SomeArrayItem
( SomeArrayItem(..)
, someArrayItemSchema
) where

import qualified Fleece.Core as FC
import Prelude (Bool, Eq, Show)

newtype SomeArrayItem = SomeArrayItem Bool
deriving (Show, Eq)

someArrayItemSchema :: FC.Fleece schema => schema SomeArrayItem
someArrayItemSchema =
FC.coerceSchema FC.boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineArrayNullableOneOf
( MinItemsOneInlineArrayNullableOneOf(..)
, minItemsOneInlineArrayNullableOneOfSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (Eq, Show)
import qualified TestCases.Types.MinItemsOneInlineArrayNullableOneOf.MinItemsOneInlineArrayNullableOneOfItem as MinItemsOneInlineArrayNullableOneOfItem

newtype MinItemsOneInlineArrayNullableOneOf = MinItemsOneInlineArrayNullableOneOf (NEL.NonEmpty MinItemsOneInlineArrayNullableOneOfItem.MinItemsOneInlineArrayNullableOneOfItem)
deriving (Show, Eq)

minItemsOneInlineArrayNullableOneOfSchema :: FC.Fleece schema => schema MinItemsOneInlineArrayNullableOneOf
minItemsOneInlineArrayNullableOneOfSchema =
FC.coerceSchema (FC.nonEmpty MinItemsOneInlineArrayNullableOneOfItem.minItemsOneInlineArrayNullableOneOfItemSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineArrayNullableOneOf.MinItemsOneInlineArrayNullableOneOfItem
( MinItemsOneInlineArrayNullableOneOfItem(..)
, minItemsOneInlineArrayNullableOneOfItemSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (($), Bool, Either, Eq, Show)
import qualified Shrubbery as Shrubbery

newtype MinItemsOneInlineArrayNullableOneOfItem = MinItemsOneInlineArrayNullableOneOfItem (Shrubbery.Union
'[ Either FC.Null (NEL.NonEmpty Bool)
])
deriving (Show, Eq)

minItemsOneInlineArrayNullableOneOfItemSchema :: FC.Fleece schema => schema MinItemsOneInlineArrayNullableOneOfItem
minItemsOneInlineArrayNullableOneOfItemSchema =
FC.coerceSchema $
FC.unionNamed (FC.qualifiedName "TestCases.Types.MinItemsOneInlineArrayNullableOneOf.MinItemsOneInlineArrayNullableOneOfItem" "MinItemsOneInlineArrayNullableOneOfItem") $
FC.unionMember (FC.nullable (FC.nonEmpty FC.boolean))
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineArrayOneOf
( MinItemsOneInlineArrayOneOf(..)
, minItemsOneInlineArrayOneOfSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (Eq, Show)
import qualified TestCases.Types.MinItemsOneInlineArrayOneOf.MinItemsOneInlineArrayOneOfItem as MinItemsOneInlineArrayOneOfItem

newtype MinItemsOneInlineArrayOneOf = MinItemsOneInlineArrayOneOf (NEL.NonEmpty MinItemsOneInlineArrayOneOfItem.MinItemsOneInlineArrayOneOfItem)
deriving (Show, Eq)

minItemsOneInlineArrayOneOfSchema :: FC.Fleece schema => schema MinItemsOneInlineArrayOneOf
minItemsOneInlineArrayOneOfSchema =
FC.coerceSchema (FC.nonEmpty MinItemsOneInlineArrayOneOfItem.minItemsOneInlineArrayOneOfItemSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineArrayOneOf.MinItemsOneInlineArrayOneOfItem
( MinItemsOneInlineArrayOneOfItem(..)
, minItemsOneInlineArrayOneOfItemSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (($), Bool, Eq, Show)
import qualified Shrubbery as Shrubbery

newtype MinItemsOneInlineArrayOneOfItem = MinItemsOneInlineArrayOneOfItem (Shrubbery.Union
'[ (NEL.NonEmpty Bool)
])
deriving (Show, Eq)

minItemsOneInlineArrayOneOfItemSchema :: FC.Fleece schema => schema MinItemsOneInlineArrayOneOfItem
minItemsOneInlineArrayOneOfItemSchema =
FC.coerceSchema $
FC.unionNamed (FC.qualifiedName "TestCases.Types.MinItemsOneInlineArrayOneOf.MinItemsOneInlineArrayOneOfItem" "MinItemsOneInlineArrayOneOfItem") $
FC.unionMember (FC.nonEmpty FC.boolean)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineObjectOneOf
( MinItemsOneInlineObjectOneOf(..)
, minItemsOneInlineObjectOneOfSchema
) where

import qualified Data.List.NonEmpty as NEL
import Fleece.Core ((#+))
import qualified Fleece.Core as FC
import Prelude (($), Eq, Maybe, Show)
import qualified TestCases.Types.MinItemsOneInlineObjectOneOf.SomeArrayItem as SomeArrayItem

data MinItemsOneInlineObjectOneOf = MinItemsOneInlineObjectOneOf
{ someArray :: Maybe (NEL.NonEmpty SomeArrayItem.SomeArrayItem)
}
deriving (Eq, Show)

minItemsOneInlineObjectOneOfSchema :: FC.Fleece schema => schema MinItemsOneInlineObjectOneOf
minItemsOneInlineObjectOneOfSchema =
FC.object $
FC.constructor MinItemsOneInlineObjectOneOf
#+ FC.optional "someArray" someArray (FC.nonEmpty SomeArrayItem.someArrayItemSchema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}

module TestCases.Types.MinItemsOneInlineObjectOneOf.SomeArrayItem
( SomeArrayItem(..)
, someArrayItemSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Fleece.Core as FC
import Prelude (($), Bool, Eq, Show)
import qualified Shrubbery as Shrubbery

newtype SomeArrayItem = SomeArrayItem (Shrubbery.Union
'[ (NEL.NonEmpty Bool)
])
deriving (Show, Eq)

someArrayItemSchema :: FC.Fleece schema => schema SomeArrayItem
someArrayItemSchema =
FC.coerceSchema $
FC.unionNamed (FC.qualifiedName "TestCases.Types.MinItemsOneInlineObjectOneOf.SomeArrayItem" "SomeArrayItem") $
FC.unionMember (FC.nonEmpty FC.boolean)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module TestCases.Types.OneOfWithNullable
, oneOfWithNullableSchema
) where

import qualified Data.List.NonEmpty as NEL
import qualified Data.Text as T
import Fleece.Core ((#|))
import qualified Fleece.Core as FC
Expand All @@ -20,6 +21,8 @@ newtype OneOfWithNullable = OneOfWithNullable (Shrubbery.Union
, [AStringType.AStringType]
, Either FC.Null [AStringType.AStringType]
, [Either FC.Null [AStringType.AStringType]]
, (NEL.NonEmpty (Either FC.Null [AStringType.AStringType]))
, [Either FC.Null (NEL.NonEmpty AStringType.AStringType)]
])
deriving (Show, Eq)

Expand All @@ -32,4 +35,6 @@ oneOfWithNullableSchema =
#| FC.unionMember (FC.nullable (FC.list (FC.nullable FC.text)))
#| FC.unionMember (FC.list AStringType.aStringTypeSchema)
#| FC.unionMember (FC.nullable (FC.list AStringType.aStringTypeSchema))
#| FC.unionMember (FC.list (FC.nullable (FC.list AStringType.aStringTypeSchema)))
#| FC.unionMember (FC.list (FC.nullable (FC.list AStringType.aStringTypeSchema)))
#| FC.unionMember (FC.nonEmpty (FC.nullable (FC.list AStringType.aStringTypeSchema)))
#| FC.unionMember (FC.list (FC.nullable (FC.nonEmpty AStringType.aStringTypeSchema)))
12 changes: 10 additions & 2 deletions json-fleece-openapi3/examples/test-cases/test-cases.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,16 @@ library
TestCases.Types.JustAdditionalPropertiesSchemaRef
TestCases.Types.JustAdditionalPropertiesTrue
TestCases.Types.LocalTimeType
TestCases.Types.MinLengthOne
TestCases.Types.MinLengthOne.MinLengthOneItem
TestCases.Types.MinItemsOne
TestCases.Types.MinItemsOne.MinItemsOneItem
TestCases.Types.MinItemsOneInline
TestCases.Types.MinItemsOneInline.SomeArrayItem
TestCases.Types.MinItemsOneInlineArrayNullableOneOf
TestCases.Types.MinItemsOneInlineArrayNullableOneOf.MinItemsOneInlineArrayNullableOneOfItem
TestCases.Types.MinItemsOneInlineArrayOneOf
TestCases.Types.MinItemsOneInlineArrayOneOf.MinItemsOneInlineArrayOneOfItem
TestCases.Types.MinItemsOneInlineObjectOneOf
TestCases.Types.MinItemsOneInlineObjectOneOf.SomeArrayItem
TestCases.Types.MixedInAdditionalPropertiesFalse
TestCases.Types.MixedInAdditionalPropertiesFalse.Bar
TestCases.Types.MixedInAdditionalPropertiesFalse.Foo
Expand Down
Loading

0 comments on commit 93e7955

Please sign in to comment.