Normalize top-level Array element types

This commit is contained in:
Alex Biehl 2022-02-17 09:52:57 +01:00
parent be455cf7a6
commit 2c804ff303
5 changed files with 138 additions and 6 deletions

View File

@ -35,6 +35,7 @@ import Tie.Name
apiHaskellModuleName,
cabalFileName,
fromText,
inlineArrayElementTypeName,
inlineObjectTypeName,
inlineVariantTypeName,
responseHaskellFileName,
@ -102,6 +103,9 @@ normalize =
( \enclosingType ith ->
pure (inlineVariantTypeName enclosingType ith)
)
( \enclosingType ->
pure (inlineArrayElementTypeName enclosingType)
)
generate :: MonadIO m => Writer m -> FilePath -> m ()
generate write inputFile = do

View File

@ -23,17 +23,18 @@ module Tie.Name
toOperationHaskellModuleName,
toResponseHaskellFileName,
toResponseHaskellModuleName,
toApiResponseTypeName,
toApiResponseConstructorName,
toApiDefaultResponseConstructorName,
toApiMemberName,
toEnumConstructorName,
apiHaskellModuleName,
apiHaskellFileName,
responseHaskellModuleName,
responseHaskellFileName,
inlineObjectTypeName,
inlineVariantTypeName,
toApiResponseTypeName,
toApiResponseConstructorName,
toApiDefaultResponseConstructorName,
toApiMemberName,
toEnumConstructorName,
inlineArrayElementTypeName,
)
where
@ -183,6 +184,13 @@ inlineVariantTypeName (Name parentType) ith =
escapeKeyword $
capitalizeFirstLetter (Text.unpack parentType) <> "OneOf" <> show ith
inlineArrayElementTypeName :: Name -> Name
inlineArrayElementTypeName (Name parentType) =
Name $
Text.pack $
escapeKeyword $
capitalizeFirstLetter (Text.unpack parentType) <> "Elem"
lowerFirstLetter :: String -> String
lowerFirstLetter [] = []
lowerFirstLetter (x : xs) = toLower x : xs

View File

@ -429,6 +429,8 @@ normalizeTypeShallow ::
-- | Assign a name to an anonnymous type in the ith constructor of a
-- variant type
(Name -> Int -> m Name) ->
-- | Assign a name to an anonnymous element type of an array
(Name -> m Name) ->
-- | Name of the type to normalize
Name ->
-- | Type to normalize
@ -437,6 +439,7 @@ normalizeTypeShallow ::
normalizeTypeShallow
assignObjectFieldTypeName
assignOneOfTypeName
assignArrayElemTypeName
typeName
typ
| Just variants <- isOneOfType typ = do
@ -447,7 +450,11 @@ normalizeTypeShallow
(objectType, inlineDefinitions) <-
normalizeObjectType (assignObjectFieldTypeName typeName) objectType
pure (Object objectType, inlineDefinitions)
-- There is no need to handle Enums and Arrays here. Remember this is
| Just elemType <- isArrayType typ = do
(normedElemType, inlineDefinitions) <-
normalizeNamedType (assignArrayElemTypeName typeName) elemType
pure (Array normedElemType, inlineDefinitions)
-- There is no need to handle Enums here. Remember this is
-- only called on types that already have names.
| otherwise =
pure (typ, [])
@ -461,6 +468,8 @@ normalizeType ::
-- | Assign a name to an anonnymous type in the ith constructor of a
-- variant type
(Name -> Int -> m Name) ->
-- | Assign a name to an anonnymous element type of an array
(Name -> m Name) ->
-- | Name of the type to normalize
Name ->
-- | Type to normalize
@ -469,6 +478,7 @@ normalizeType ::
normalizeType
assignObjectFieldTypeName
assignOneOfTypeName
assignArrayElemTypeName
typeName
typ = do
-- Normalize the type.
@ -476,6 +486,7 @@ normalizeType
normalizeTypeShallow
assignObjectFieldTypeName
assignOneOfTypeName
assignArrayElemTypeName
typeName
typ
-- Now, normalize the inline definitions recursively to ensure
@ -487,6 +498,7 @@ normalizeType
normalizeType
assignObjectFieldTypeName
assignOneOfTypeName
assignArrayElemTypeName
inlineDefName
inlineDefType
pure

View File

@ -35,6 +35,21 @@ paths:
type: array
items:
$ref: "#/components/schemas/Package"
/packages3:
get:
summary: List all packages
operationId: listPackages3
tags:
- packages
responses:
'200':
description: An inline array of packages
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Inline"
components:
schemas:
Package:
@ -45,3 +60,9 @@ components:
type: array
items:
$ref: "#/components/schemas/Package"
Inline:
type: array
items:
properties:
name:
type: string

View File

@ -22,13 +22,16 @@ import qualified Web.HttpApiData
import OpenAPI.Response
import OpenAPI.Schemas.Packages
import OpenAPI.Schemas.Inline
import OpenAPI.Schemas.Package
import OpenAPI.Response.ListPackages
import OpenAPI.Response.ListPackages3
import OpenAPI.Response.ListPackages2
data Api m = Api {
listPackages :: m ListPackagesResponse,
listPackages3 :: m ListPackages3Response,
listPackages2 :: m ListPackages2Response
}
@ -53,6 +56,15 @@ application run api notFound request respond =
x ->
unsupportedMethod x
[ "packages3" ] ->
case Network.Wai.requestMethod request of
"GET" ->
run request $ do
response <- listPackages3 api
Control.Monad.IO.Class.liftIO (respond (toResponse response))
x ->
unsupportedMethod x
_ ->
notFound request respond
where
@ -149,6 +161,79 @@ instance ToResponse ListPackages2Response where
toResponse (ListPackages2Response200 x) =
Network.Wai.responseBuilder (toEnum 200) [(Network.HTTP.Types.hContentType, "application/json")] (Data.Aeson.fromEncoding (Data.Aeson.toEncoding x))
---------------------
OpenAPI/Response/ListPackages3.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module OpenAPI.Response.ListPackages3 where
import qualified Control.Applicative
import qualified Control.Monad.IO.Class
import qualified Data.Aeson
import qualified Data.Aeson.Parser
import qualified Data.Aeson.Types
import qualified Data.Attoparsec.ByteString
import qualified Data.Maybe
import qualified Data.Text
import qualified GHC.Types
import qualified Network.HTTP.Types
import qualified Network.Wai
import qualified Web.HttpApiData
import OpenAPI.Schemas.Inline
import OpenAPI.Response
data ListPackages3Response
= ListPackages3Response200 [ Inline ]
instance ToResponse ListPackages3Response where
toResponse (ListPackages3Response200 x) =
Network.Wai.responseBuilder (toEnum 200) [(Network.HTTP.Types.hContentType, "application/json")] (Data.Aeson.fromEncoding (Data.Aeson.toEncoding x))
---------------------
OpenAPI/Schemas/Inline.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module OpenAPI.Schemas.Inline where
import qualified Control.Applicative
import qualified Control.Monad.IO.Class
import qualified Data.Aeson
import qualified Data.Aeson.Parser
import qualified Data.Aeson.Types
import qualified Data.Attoparsec.ByteString
import qualified Data.Maybe
import qualified Data.Text
import qualified GHC.Types
import qualified Network.HTTP.Types
import qualified Network.Wai
import qualified Web.HttpApiData
newtype InlineElem = InlineElem
{
name :: Data.Maybe.Maybe (Data.Text.Text)
}
instance Data.Aeson.ToJSON InlineElem where
toJSON InlineElem {..} = Data.Aeson.object
[
"name" Data.Aeson..= name
]
instance Data.Aeson.FromJSON InlineElem where
parseJSON = Data.Aeson.withObject "InlineElem" $ \o ->
InlineElem
<$> o Data.Aeson..:? "name"
type Inline = [ InlineElem ]
---------------------
OpenAPI/Schemas/Package.hs
{-# LANGUAGE DuplicateRecordFields #-}
@ -237,5 +322,7 @@ library
OpenAPI.Response
OpenAPI.Response.ListPackages
OpenAPI.Response.ListPackages2
OpenAPI.Response.ListPackages3
OpenAPI.Schemas.Inline
OpenAPI.Schemas.Package
OpenAPI.Schemas.Packages