diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java index 01fe6c6eed..2ee227fea2 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RubyClientCodegen.java @@ -48,12 +48,21 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { languageSpecificPrimitives.add("string"); languageSpecificPrimitives.add("DateTime"); - typeMapping.put("long", "int"); - typeMapping.put("integer", "int"); - typeMapping.put("Array", "array"); - typeMapping.put("String", "string"); - typeMapping.put("List", "array"); - typeMapping.put("map", "map"); + typeMapping.put("string", "String"); + typeMapping.put("char", "String"); + typeMapping.put("int", "Integer"); + typeMapping.put("integer", "Integer"); + typeMapping.put("long", "Integer"); + typeMapping.put("short", "Integer"); + typeMapping.put("float", "Float"); + typeMapping.put("double", "Float"); + typeMapping.put("number", "Float"); + typeMapping.put("DateTime", "DateTime"); + typeMapping.put("boolean", "BOOLEAN"); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Hash"); + typeMapping.put("object", "Hash"); String baseFolder = "lib" + File.separatorChar + gemName; String swaggerFolder = baseFolder + File.separatorChar + "swagger"; @@ -107,11 +116,11 @@ public class RubyClientCodegen extends DefaultCodegen implements CodegenConfig { if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; Property inner = ap.getItems(); - return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">"; } else if (p instanceof MapProperty) { MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); - return getSwaggerType(p) + "[string," + getTypeDeclaration(inner) + "]"; + return getSwaggerType(p) + ""; } return super.getTypeDeclaration(p); } diff --git a/modules/swagger-codegen/src/main/resources/ruby/api.mustache b/modules/swagger-codegen/src/main/resources/ruby/api.mustache index 3e1ac14014..2b0f17c63f 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api.mustache @@ -51,8 +51,8 @@ module {{moduleName}} {{/bodyParam}} auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}] - {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make.body - {{#returnContainer}}response.map {|response| {{/returnContainer}}obj = {{returnBaseType}}.new() and obj.build_from_hash(response){{#returnContainer}} }{{/returnContainer}}{{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + {{#returnType}}response = Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params, :headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make + response.deserialize('{{{returnType}}}'){{/returnType}}{{^returnType}}Swagger::Request.new(:{{httpMethod}}, path, {:params => query_params,:headers => header_params, :form_params => form_params, :body => post_body, :auth_names => auth_names}).make nil{{/returnType}} end {{/operation}} diff --git a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache index c0e563a0bb..2f1e1064a5 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/base_object.mustache @@ -15,7 +15,7 @@ module {{moduleName}} def build_from_hash(attributes) return nil unless attributes.is_a?(Hash) self.class.swagger_types.each_pair do |key, type| - if type =~ /^array\[(.*)\]/i + if type =~ /^Array<(.*)>/i if attributes[self.class.attribute_map[key]].is_a?(Array) self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) else @@ -35,13 +35,13 @@ module {{moduleName}} case type.to_sym when :DateTime DateTime.parse(value) - when :string + when :String value.to_s - when :int + when :Integer value.to_i - when :double + when :Float value.to_f - when :boolean + when :BOOLEAN if value =~ /^(true|t|yes|y|1)$/i true else diff --git a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache index e7bb482fb6..3abc7df40d 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/swagger/response.mustache @@ -2,6 +2,7 @@ module {{moduleName}} module Swagger class Response require 'json' + require 'date' attr_accessor :raw @@ -9,8 +10,8 @@ module {{moduleName}} self.raw = raw case self.code - when 500..510 then raise(ServerError, self.error_message) - when 299..426 then raise(ClientError, self.error_message) + when 500..510 then raise(ServerError, self.body) + when 299..426 then raise(ClientError, self.body) end end @@ -18,19 +19,58 @@ module {{moduleName}} raw.code end - # Account for error messages that take different forms... - def error_message - body['message'] - rescue - body + def body + raw.body end - # If body is JSON, parse it - # Otherwise return raw string - def body - JSON.parse(raw.body, :symbolize_names => true) - rescue - raw.body + # Deserialize the raw response body to the given return type. + # + # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]" + def deserialize(return_type) + return nil if body.blank? + + # ensuring a default content type + content_type = raw.headers_hash['Content-Type'] || 'application/json' + + unless content_type.start_with?('application/json') + fail "Content-Type is not supported: #{content_type}" + end + + begin + data = JSON.parse(body, :symbolize_names => true) + rescue JSON::ParserError => e + if return_type == 'String' + return body + else + raise e + end + end + + build_models data, return_type + end + + # Build model(s) from Hash data for array/hash values of the response. + def build_models(data, return_type) + case return_type + when /\AArray<(.+)>\z/ + sub_type = $1 + data.map {|item| build_models(item, sub_type) } + when /\AHash\\z/ + sub_type = $1 + {}.tap do |hash| + data.each {|k, v| hash[k] = build_models(v, sub_type) } + end + when 'String', 'Integer', 'Float', 'BOOLEAN' + # primitives, return directly + data + when 'DateTime' + DateTime.parse data + else + # models + {{moduleName}}.const_get(return_type).new.tap do |model| + model.build_from_hash data + end + end end # `headers_hash` is a Typhoeus-specific extension of Hash, @@ -58,7 +98,7 @@ module {{moduleName}} def pretty_body return unless body.present? case format - when 'json' then JSON.pretty_generate(body).gsub(/\n/, '
') + when 'json' then JSON.pretty_generate(JSON.parse(body)).gsub(/\n/, '
') end end