Skip to content

Commit

Permalink
In case of a single error, don't define a custom type
Browse files Browse the repository at this point in the history
  • Loading branch information
miniBill committed Aug 3, 2024
1 parent dc858ec commit d2c26aa
Showing 1 changed file with 105 additions and 97 deletions.
202 changes: 105 additions & 97 deletions src/OpenApi/Generate.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2064,91 +2064,96 @@ operationToTypesExpectAndResolver namespace functionName operation =

errorDecoders : CliMonad Elm.Expression
errorDecoders =
errorResponses
|> Dict.map
(\statusCode errResponseOrRef ->
case OpenApi.Reference.toConcrete errResponseOrRef of
Just errResponse ->
OpenApi.Response.content errResponse
|> contentToContentSchema True namespace
|> CliMonad.andThen
(\contentSchema ->
case contentSchema of
JsonContent type_ ->
SchemaUtils.typeToDecoder True namespace type_
|> CliMonad.map
(Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Types
, name = toErrorVariant statusCode
, annotation = Nothing
}
|> Gen.Json.Decode.call_.map
)

StringContent _ ->
CliMonad.succeed Gen.Json.Decode.string
|> CliMonad.map
(Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Types
, name = toErrorVariant statusCode
, annotation = Nothing
}
|> Gen.Json.Decode.call_.map
)
case Dict.toList errorResponses of
[] ->
Elm.list []
|> Gen.Dict.call_.fromList
|> CliMonad.succeed

errorList ->
errorList
|> CliMonad.combineMap
(\( statusCode, errResponseOrRef ) ->
let
single : Bool
single =
case errorList of
[ _ ] ->
True

BytesContent _ ->
CliMonad.todo "Bytes errors are not supported yet"
_ ->
False

EmptyContent ->
CliMonad.succeed (Gen.Json.Decode.succeed Elm.unit)
|> CliMonad.map
(Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Types
, name = toErrorVariant statusCode
, annotation = Nothing
}
|> Gen.Json.Decode.call_.map
)
)
common : Elm.Expression -> Elm.Expression
common decoder =
Elm.tuple
(Elm.string statusCode)
(if single then
decoder

Nothing ->
CliMonad.succeed errResponseOrRef
|> CliMonad.stepOrFail "I found an error response, but I couldn't convert it to a concrete decoder"
OpenApi.Reference.toReference
|> CliMonad.andThen
(\ref ->
let
inner : String
inner =
OpenApi.Reference.ref ref
in
SchemaUtils.refToTypeName (String.split "/" inner)
|> CliMonad.map
(\typeName ->
Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Json
, name = "decode" ++ typeName
, annotation = Nothing
}
)
|> CliMonad.map
else
Gen.Json.Decode.call_.map
(Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Types
, name = toErrorVariant statusCode
, annotation = Nothing
}
|> Gen.Json.Decode.call_.map
)
)
)
|> CliMonad.combineDict
|> CliMonad.map
(\decoders ->
Dict.toList decoders
|> List.map (\( k, v ) -> Elm.tuple (Elm.string k) v)
|> Elm.list
|> Gen.Dict.call_.fromList
)
decoder
)
in
case OpenApi.Reference.toConcrete errResponseOrRef of
Just errResponse ->
OpenApi.Response.content errResponse
|> contentToContentSchema True namespace
|> CliMonad.andThen
(\contentSchema ->
case contentSchema of
JsonContent type_ ->
SchemaUtils.typeToDecoder True namespace type_
|> CliMonad.map common

StringContent _ ->
CliMonad.succeed Gen.Json.Decode.string
|> CliMonad.map common

BytesContent _ ->
CliMonad.todo "Bytes errors are not supported yet"

EmptyContent ->
CliMonad.succeed (Gen.Json.Decode.succeed Elm.unit)
|> CliMonad.map common
)

Nothing ->
CliMonad.succeed errResponseOrRef
|> CliMonad.stepOrFail "I found an error response, but I couldn't convert it to a concrete decoder"
OpenApi.Reference.toReference
|> CliMonad.andThen
(\ref ->
let
inner : String
inner =
OpenApi.Reference.ref ref
in
SchemaUtils.refToTypeName (String.split "/" inner)
|> CliMonad.map
(\typeName ->
Elm.value
{ importFrom = Common.moduleToNamespace namespace Common.Json
, name = "decode" ++ typeName
, annotation = Nothing
}
)
|> CliMonad.map common
)
)
|> CliMonad.map
(\decoders ->
decoders
|> Elm.list
|> Gen.Dict.call_.fromList
)

errorTypeDeclaration : CliMonad ( Maybe Elm.Declaration, Elm.Annotation.Annotation )
errorTypeDeclaration =
Expand Down Expand Up @@ -2196,28 +2201,31 @@ operationToTypesExpectAndResolver namespace functionName operation =
|> CliMonad.combineDict
|> CliMonad.map
(\dict ->
if Dict.isEmpty dict then
( Nothing
, Elm.Annotation.var "e"
)
case Dict.toList dict of
[] ->
( Nothing
, Elm.Annotation.var "e"
)

else
let
errorName : String
errorName =
String.Extra.toSentenceCase functionName ++ "_Error"
in
( dict
|> Dict.toList
|> List.map (\( statusCode, annotation ) -> Elm.variantWith (toErrorVariant statusCode) [ annotation ])
|> Elm.customType errorName
|> Elm.exposeWith
{ exposeConstructor = True
, group = Just "Errors"
}
|> Just
, Elm.Annotation.named (Common.moduleToNamespace namespace Common.Types) errorName
)
[ ( _, annotation ) ] ->
( Nothing, annotation )

errorList ->
let
errorName : String
errorName =
String.Extra.toSentenceCase functionName ++ "_Error"
in
( errorList
|> List.map (\( statusCode, annotation ) -> Elm.variantWith (toErrorVariant statusCode) [ annotation ])
|> Elm.customType errorName
|> Elm.exposeWith
{ exposeConstructor = True
, group = Just "Errors"
}
|> Just
, Elm.Annotation.named (Common.moduleToNamespace namespace Common.Types) errorName
)
)
in
case OpenApi.Reference.toConcrete responseOrRef of
Expand Down

0 comments on commit d2c26aa

Please sign in to comment.