From 17af708b064f33da618c62c20c3cadd303ab2611 Mon Sep 17 00:00:00 2001 From: Erik Timmers Date: Thu, 23 May 2019 20:22:53 +0200 Subject: [PATCH] Add support for enums in Elm operations --- .../codegen/languages/ElmClientCodegen.java | 74 +++++++++++-------- .../src/main/resources/elm/api.mustache | 29 +++++++- .../client/petstore/elm/src/Request/Pet.elm | 25 ++++++- 3 files changed, 91 insertions(+), 37 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java index b92d62445bc9..8058a07b6b59 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java @@ -567,44 +567,56 @@ private String toOptionalValue(String value) { return "(Just " + value + ")"; } + private Optional paramToStringMapper(final String paramName, final CodegenProperty property) { + if (property.isEnum) { + return Optional.of(toVarName(paramName) + "ToString"); + } else if (property.isString || property.isBinary || property.isByteArray) { + return Optional.empty(); + } else if (property.isBoolean) { + return Optional.of("(\\val -> if val then \"true\" else \"false\")"); + } else if (property.isDateTime) { + return Optional.of("DateTime.toString"); + } else if (property.isDate) { + return Optional.of("DateOnly.toString"); + } else if (property.isUuid) { + return Optional.of("Uuid.toString"); + } else if (ElmVersion.ELM_018.equals(elmVersion)) { + return Optional.of("toString"); + } else if (property.isInteger || property.isLong) { + return Optional.of("String.fromInt"); + } else if (property.isFloat || property.isDouble) { + return Optional.of("String.fromFloat"); + } + throw new RuntimeException("Parameter '" + paramName + "' cannot be converted to a string. Please report the issue."); + } + + private CodegenProperty paramToProperty(final CodegenParameter parameter) { + final CodegenProperty property = new CodegenProperty(); + property.isEnum = parameter.isEnum; + property.isString = parameter.isString; + property.isBinary = parameter.isBinary; + property.isByteArray = parameter.isByteArray; + property.isBoolean = parameter.isBoolean; + property.isDateTime = parameter.isDateTime; + property.isDate = parameter.isDate; + property.isUuid = parameter.isUuid; + property.isInteger = parameter.isInteger; + property.isLong = parameter.isLong; + property.isFloat = parameter.isFloat; + property.isDouble = parameter.isDouble; + return property; + } + private String paramToString(final String prefix, final CodegenParameter param, final boolean useMaybe, final String maybeMapResult) { final String paramName = (ElmVersion.ELM_018.equals(elmVersion) ? "" : prefix + ".") + param.paramName; if (!useMaybe) { param.required = true; } - String mapFn = null; - if (param.isString || param.isBinary || param.isByteArray) { - mapFn = ""; - } else if (param.isBoolean) { - mapFn = "(\\val -> if val then \"true\" else \"false\")"; - } else if (param.isDateTime) { - mapFn = "DateTime.toString"; - } else if (param.isDate) { - mapFn = "DateOnly.toString"; - } else if (param.isUuid) { - mapFn = "Uuid.toString"; - } else if (ElmVersion.ELM_018.equals(elmVersion)) { - mapFn = "toString"; - } else if (param.isInteger || param.isLong) { - mapFn = "String.fromInt"; - } else if (param.isFloat || param.isDouble) { - mapFn = "String.fromFloat"; - } else if (param.isListContainer) { - // TODO duplicate ALL types from parameter to property... - if (param.items.isString || param.items.isUuid || param.items.isBinary || param.items.isByteArray) { - mapFn = "String.join \",\""; - } - } - if (mapFn == null) { - throw new RuntimeException("Parameter '" + param.paramName + "' cannot be converted to a string. Please report the issue."); - } + final String mapFn = param.isListContainer + ? "(String.join \",\"" + paramToStringMapper(param.paramName, param.items).map(mapper -> " << List.map " + mapper).orElse("") + ")" + : paramToStringMapper(param.paramName, paramToProperty(param)).orElse(""); - if (param.isListContainer) { - if (!param.required) { - mapFn = "(" + mapFn + ")"; - } - } String mapResult = ""; if (maybeMapResult != null) { if ("".equals(mapFn)) { diff --git a/modules/openapi-generator/src/main/resources/elm/api.mustache b/modules/openapi-generator/src/main/resources/elm/api.mustache index 16c4e3a5ba57..275a9121920a 100644 --- a/modules/openapi-generator/src/main/resources/elm/api.mustache +++ b/modules/openapi-generator/src/main/resources/elm/api.mustache @@ -1,6 +1,6 @@ {{>licenseInfo}} -module Request.{{classname}} exposing ({{#operations}}{{#operation}}{{^-first}}, {{/-first}}{{operationId}}{{/operation}}{{/operations}}) +module Request.{{classname}} exposing ({{#operations}}{{#operation}}{{^-first}}, {{/-first}}{{operationId}}{{#allParams}}{{#isEnum}}, {{enumName}}(..){{/isEnum}}{{/allParams}}{{/operation}}{{/operations}}) {{>imports}}import Dict import Http @@ -8,6 +8,29 @@ import Json.Decode as Decode import Url.Builder as Url +{{#operations}} +{{#operation}} +{{#allParams}} +{{#isEnum}} +type {{enumName}} +{{#allowableValues.enumVars}} {{#-first}}= {{/-first}}{{^-first}}| {{/-first}}{{name}} +{{/allowableValues.enumVars}} + +{{paramName}}ToString : {{enumName}} -> String +{{paramName}}ToString value = + case value of +{{#allowableValues.enumVars}} {{name}} -> + {{{value}}} + +{{/allowableValues.enumVars}} + + +{{/isEnum}} +{{/allParams}} +{{/operation}} +{{/operations}} + + {{^enableCustomBasePaths}}basePath : String basePath = "{{basePath}}" @@ -29,8 +52,8 @@ basePath = {{#enableCustomBasePaths}} , basePath : String{{/enableCustomBasePaths}} {{#enableHttpRequestTrackers}} , tracker : Maybe String{{/enableHttpRequestTrackers}} {{#bodyParam}} , body : {{^required}}Maybe {{/required}}{{dataType}}{{/bodyParam}} -{{#pathParams}} , {{paramName}} : {{#isListContainer}}List {{/isListContainer}}{{dataType}}{{/pathParams}} -{{#queryParams}} , {{paramName}} : {{^required}}Maybe ({{/required}}{{#isListContainer}}List {{/isListContainer}}{{dataType}}{{^required}}){{/required}}{{/queryParams}} +{{#pathParams}} , {{paramName}} : {{#isListContainer}}List {{/isListContainer}}{{#datatypeWithEnum}}{{datatypeWithEnum}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{dataType}}{{/datatypeWithEnum}}{{/pathParams}} +{{#queryParams}} , {{paramName}} : {{^required}}Maybe ({{/required}}{{#isListContainer}}List {{/isListContainer}}{{#datatypeWithEnum}}{{datatypeWithEnum}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{dataType}}{{/datatypeWithEnum}}{{^required}}){{/required}}{{/queryParams}} } -> Cmd msg {{operationId}} {{#headerParams.0}}headers {{/headerParams.0}}params = diff --git a/samples/client/petstore/elm/src/Request/Pet.elm b/samples/client/petstore/elm/src/Request/Pet.elm index 017cdb0a8c05..1743382c61ed 100644 --- a/samples/client/petstore/elm/src/Request/Pet.elm +++ b/samples/client/petstore/elm/src/Request/Pet.elm @@ -10,7 +10,7 @@ -} -module Request.Pet exposing (addPet, deletePet, findPetsByStatus, findPetsByTags, getPetById, updatePet, updatePetWithForm, uploadFile) +module Request.Pet exposing (Status(..), addPet, deletePet, findPetsByStatus, findPetsByTags, getPetById, updatePet, updatePetWithForm, uploadFile) import Data.ApiResponse as ApiResponse exposing (ApiResponse) import Data.Pet as Pet exposing (Pet) @@ -20,6 +20,25 @@ import Json.Decode as Decode import Url.Builder as Url +type Status + = Available + | Pending + | Sold + + +statusToString : Status -> String +statusToString value = + case value of + Available -> + "available" + + Pending -> + "pending" + + Sold -> + "sold" + + basePath : String basePath = "http://petstore.swagger.io/v2" @@ -72,7 +91,7 @@ deletePet headers params = -} findPetsByStatus : { onSend : Result Http.Error (List Pet) -> msg - , status : List String + , status : List Status } -> Cmd msg findPetsByStatus params = @@ -82,7 +101,7 @@ findPetsByStatus params = , url = Url.crossOrigin basePath [ "pet", "findByStatus" ] - (List.filterMap identity [ Just (Url.string "status" <| String.join "," params.status) ]) + (List.filterMap identity [ Just (Url.string "status" <| (String.join "," << List.map statusToString) params.status) ]) , body = Http.emptyBody , expect = Http.expectJson params.onSend (Decode.list Pet.decoder) , timeout = Just 30000